ADR-001: Smart Office Meeting Room Access System
1. Context
The company wants to improve meeting-room management by providing:
- A tablet/display outside each meeting room.
- Room name and meeting information on the display.
- Current and upcoming meetings.
- Employee access using existing 13.56 MHz MIFARE RFID cards.
- Door access only when the employee is authorized for the current meeting.
- A fallback PIN mechanism when an employee cannot use their RFID card.
- Centralized management by HR/office administrators.
- Operation primarily on the company's local network.
For the MVP, meeting bookings will be managed manually by the HR/office team. Employees will not directly create bookings through the system.
Remote booking through VPN or Internet access is explicitly out of scope for the initial version.
2. Decision
We will build a LAN-based smart meeting-room system consisting of:
Software
-
TanStack Start
-
Admin interface
- Meeting-room tablet interface
- Backend/server functions/API
- Authorization/business logic
- React + TypeScript
- PostgreSQL
- Docker / Docker Compose
- Local deployment on a company-controlled server
Room hardware
- Android tablet in kiosk mode
-
ZKTeco access-control device with:
-
13.56 MHz MIFARE/MF RFID support
- TCP/IP networking
- Relay output
- Door sensor input
- Exit-button input
-
Electric door lock
-
Magnetic lock or electric strike, depending on the actual door
- Appropriate power supply
- Door sensor
- Exit button
Network
All application communication will remain on the company LAN.
The system does not require Internet connectivity for normal operation, although Internet access may be useful for software updates, monitoring, or future functionality.
3. High-Level Architecture
flowchart TB
subgraph LAN["Company LAN"]
SERVER["Application Server<br/>Docker<br/><br/>TanStack Start<br/>PostgreSQL"]
TABLET["Android Tablet<br/>Kiosk Mode<br/><br/>Room Display<br/>PIN Fallback"]
ACCESS["ZKTeco Access Controller<br/><br/>MIFARE RFID Reader<br/>TCP/IP<br/>Relay<br/>Door Sensor Input<br/>Exit Button Input"]
end
CARD["Employee MIFARE Card"]
LOCK["Electric Door Lock"]
SENSOR["Door Sensor"]
EXIT["Exit Button"]
DOOR["Meeting Room Door"]
TABLET <-->|HTTP/HTTPS| SERVER
SERVER <-->|TCP/IP / Vendor Integration| ACCESS
CARD -->|RFID| ACCESS
ACCESS -->|Relay| LOCK
SENSOR -->|Door status| ACCESS
EXIT -->|Exit request| ACCESS
LOCK --> DOOR
4. Main Components
4.1 Application Server
4.1 Application Server
The company provides a server on the internal network.
The server runs Docker containers containing:
Application Server
│
├── TanStack Start
│ ├── Admin UI
│ ├── Tablet UI
│ ├── Backend/API
│ ├── Authentication
│ ├── Booking logic
│ └── Access authorization logic
│
└── PostgreSQL
The application server is the central source of truth for:
- Employees
- RFID credentials
- Rooms
- Tablets/devices
- Meetings
- Meeting attendees
- PINs
- Access events
5. Tablet Interface
Each meeting room has an Android tablet mounted outside the room.
The tablet runs the room interface using a browser in kiosk mode.
Example:
Tablet responsibilities
- Display room name.
- Display current meeting.
- Display upcoming meeting(s).
- Display meeting status/countdown.
- Provide PIN entry.
- Show access result.
- Provide basic error/offline state.
- Automatically reconnect if the network temporarily fails.
Tablet does NOT:
- Directly control the physical door lock.
- Directly communicate with the relay.
- Decide whether an employee is authorized.
Authorization remains a backend/access-control responsibility.
6. RFID / Access-Control Hardware
The proposed hardware category is a ZKTeco access-control terminal/controller with integrated 13.56 MHz MIFARE support, with ProRF as the initial candidate.
The exact model/configuration must be validated before purchase.
The device is responsible for the hardware-side access-control operation.
Conceptually:
MIFARE Card
│
▼
RFID Reader
│
▼
Access Controller
│
├── Relay ───────► Electric Lock
│
├── Door Sensor
│
└── Exit Button
If the selected ZKTeco device has an integrated MIFARE reader, no separate RFID reader is required.
If a separate reader is used, the reader may communicate with the access controller using RS-485/OSDP or another supported interface.
7. Electric Lock
The electric lock is the physical mechanism that locks/unlocks the meeting-room door.
Two main options should be evaluated:
Option A — Magnetic lock
Option B — Electric strike
The electric strike is installed in the door frame and works with the door's existing mechanical latch.
The choice depends on:
- Existing door construction
- Door handle/latch type
- Fire-safety requirements
- Emergency egress requirements
- Fail-safe/fail-secure requirements
- Installation constraints
The lock itself generally does not need Ethernet, Wi-Fi, or Internet.
The access controller operates it through a relay.
8. Door Sensor
A door sensor detects whether the physical door is open or closed.
A typical implementation uses a magnetic contact:
The access controller can use this information to determine:
- Whether the door actually opened after access was granted.
- Whether the door remains open.
- Whether the door was opened unexpectedly.
- Whether the door may have been forced open.
Example event sequence:
Door status can also be recorded in the application audit log if the controller exposes the relevant events.
9. Exit Button
The exit button is installed inside the meeting room.
Its purpose is to allow someone inside to leave without using an RFID card.
Typical flow:
The exit button should normally operate locally through the access controller rather than depending on the application server.
This is important because people must still be able to exit if the application server or network is unavailable.
10. Authentication Methods
The system has two access methods.
10.1 Primary: MIFARE RFID
The exact interaction between the ZKTeco controller and backend depends on the vendor's supported integration protocol/API.
11. PIN Fallback
The PIN is intended as a fallback when an employee cannot use their RFID card.
Example:
PIN security requirements
- Generate cryptographically random PINs.
- Prefer 6-digit or similarly practical PINs.
- Store only a hash of the PIN where practical.
- Give each PIN an expiration time.
- Restrict the valid time window.
- Limit failed attempts.
- Log failed attempts.
- Invalidate the PIN after use if appropriate.
- Do not expose PINs in URLs.
- Do not allow a PIN to bypass meeting authorization.
The PIN is a fallback authentication mechanism, not an unrestricted master override.
12. Authorization Rules
The backend should determine whether access is allowed.
A simplified rule is:
ALLOW if:
employee exists
AND employee is active
AND employee is authorized for the meeting
AND meeting belongs to this room
AND current time is within the permitted access window
AND authentication method is valid
Example:
Employee: E001
Room: Room 101
Meeting: Product Development
Time: 10:00 - 11:00
10:15 → RFID → ALLOW
10:15 → valid PIN → ALLOW
08:00 → RFID → DENY
12:00 → RFID → DENY
Employee not attending meeting → DENY
Wrong PIN → DENY
Expired PIN → DENY
The exact access window should be configurable.
For example, the system might allow access from 10 minutes before the meeting until the end of the meeting.
13. Booking Management
For the MVP, HR/office staff manage bookings.
There is no employee self-service booking requirement initially.
The admin interface should allow administrators to:
- Create meetings.
- Edit meetings.
- Cancel meetings.
- Assign rooms.
- Add attendees.
- View room schedules.
- Manage employees.
- Associate MIFARE credentials with employees.
- Generate/revoke PINs if necessary.
- View access logs.
- Configure rooms/tablets.
Future versions may introduce employee self-service booking through the company network or VPN.
14. Database Model
PostgreSQL is the selected database.
Initial entities:
Employee
├── id
├── employee_code
├── name
├── email
├── rfid_uid / credential reference
└── status
Room
├── id
├── name
├── location
└── status
Device
├── id
├── room_id
├── device_code
├── type
├── ip_address
└── last_seen_at
Meeting
├── id
├── room_id
├── title
├── start_time
├── end_time
├── organizer_id
└── status
MeetingAttendee
├── meeting_id
└── employee_id
AccessPin
├── id
├── meeting_id
├── employee_id
├── pin_hash
├── expires_at
├── used_at
└── attempts
AccessEvent
├── id
├── room_id
├── employee_id
├── method
├── result
├── reason
└── created_at
Database constraints should prevent problems such as:
- Duplicate RFID credentials.
- Duplicate meeting attendees.
- Invalid room references.
- Invalid employee references.
- Overlapping room bookings.
PostgreSQL should be treated as the long-term source of truth for application data and audit history.
The access controller's internal transaction storage is a hardware buffer, not the primary application database.
15. Network Architecture
The system is designed to operate entirely inside the company LAN.
The application server should ideally have a stable IP address.
Access controllers should use either:
- Static IP addresses, or
- DHCP reservations.
Example only:
Server 192.168.10.10
ZKTeco Room 101 192.168.10.101
ZKTeco Room 102 192.168.10.102
Tablet Room 101 192.168.10.201
Tablet Room 102 192.168.10.202
Actual addresses and VLANs are determined by the company's IT team.
16. Network Security
Ideally, the company should create a dedicated VLAN for smart-office equipment.
Recommended rules:
- ZKTeco devices should not require unrestricted Internet access.
- Tablets should only need access to the application.
- Access controllers should only communicate with required internal services.
- Administrative interfaces should require authentication.
- Use HTTPS where practical.
- Restrict administrative ports.
- Do not expose the application directly to the public Internet.
- Use firewall rules between VLANs where appropriate.
17. LAN Compatibility Requirements for ZKTeco
Before purchasing the access-control hardware, the following must be confirmed with the vendor/distributor:
Required
- 13.56 MHz MIFARE/MF card compatibility.
- Ethernet/TCP-IP connectivity.
- Stable IP configuration.
- Relay output suitable for the selected electric lock.
- Door sensor input.
- Exit-button input.
- Local operation when the application server is temporarily unavailable.
- Access-event retrieval.
- Remote unlock capability if the PIN workflow is to be implemented through the backend.
- Documented SDK/API/protocol for third-party integration.
Critical validation
The most important unresolved question is:
Can our TanStack Start backend communicate directly with the ZKTeco controller to receive access events and trigger the relay remotely?
TCP/IP support alone does not prove that a public application API exists.
The vendor/distributor should provide:
- SDK/API documentation.
- Communication protocol documentation.
- Authentication mechanism.
- Example integration.
- Remote unlock method.
- Event callback/push mechanism.
- Required ports.
- Whether a ZKTeco management server is required.
- Whether the device can operate without ZKTeco cloud services.
Do not purchase the hardware until this integration path is confirmed.
19. Reliability and Failure Behavior
The physical access-control layer should not depend entirely on the application server.
If the application server is temporarily unavailable
The system should still allow safe physical exit.
The access controller should retain whatever local access rules are required for emergency/normal operation.
If the network is unavailable
- Tablet may display an offline state.
- New PIN validation cannot be performed unless a local fallback mechanism exists.
- Existing local access-control behavior should continue according to the controller configuration.
- Exit from the room must remain possible.
If the tablet is unavailable
RFID access should still function independently.
If the access controller is unavailable
The application should report the room/device as offline.
Physical emergency procedures must remain available.
20. Docker Deployment
The initial deployment should remain simple.
Docker Host
│
├── tanstack-app
│
└── postgres
Example:
services:
app:
build: .
restart: unless-stopped
postgres:
image: postgres
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
The exact configuration is implementation-specific.
Do not introduce Kubernetes or microservices for the MVP.
21. Backup
Docker is not a backup solution.
PostgreSQL must have scheduled backups.
At minimum:
PostgreSQL
│
├── Daily backup
├── Backup retention
└── Separate storage
The backup strategy should be approved by the company's IT team.
Access logs and meeting data should be considered important business data.
22. Device Assignment
Each tablet and access controller should be associated with a room in the database.
Example:
Room 101
│
├── Tablet: tablet-101
└── Access Controller: access-101
Room 102
│
├── Tablet: tablet-102
└── Access Controller: access-102
The room should not be permanently hard-coded into the frontend.
Instead, the device should have a configuration/registration mechanism so an administrator can assign or reassign it.
This becomes important when the company has many meeting rooms.
23. Example Complete Access Flow
sequenceDiagram
autonumber
participant E as Employee
participant R as MIFARE Reader
participant C as ZKTeco Controller
participant B as TanStack Backend
participant DB as PostgreSQL
participant L as Electric Lock
participant D as Door
E->>R: Tap MIFARE card
R->>C: Card credential
C->>B: Access event / authorization request
B->>DB: Find employee + active meeting
DB-->>B: Meeting and attendee information
B->>B: Validate room + attendee + time
B-->>C: Access granted
C->>L: Activate relay
L-->>D: Release lock
E->>D: Open door
C->>B: Door/access event
B->>DB: Store access log
D-->>E: Door closes
24. PIN Access Flow
sequenceDiagram
autonumber
participant E as Employee
participant T as Tablet
participant B as TanStack Backend
participant DB as PostgreSQL
participant C as ZKTeco Controller
participant L as Electric Lock
E->>T: Enter PIN
T->>B: Submit PIN + room
B->>DB: Find active PIN
DB-->>B: PIN/meeting information
B->>B: Validate PIN + employee + meeting + time
B-->>C: Unlock request
C->>L: Activate relay
L-->>E: Door can open
C->>B: Access event
B->>DB: Store access log
The exact ZKTeco communication in these diagrams is intentionally abstract until the vendor's SDK/API is confirmed.
25. Technology Decisions
Area
Selected Device / Technology
Role
Status
Application framework
TanStack Start
Admin UI, tablet UI, server/API
Selected
Frontend
React + TypeScript
Admin and tablet interfaces
Selected
Database
PostgreSQL
Application data, bookings, credentials, audit logs
Selected
ORM
Drizzle ORM
Database access and type-safe queries
Proposed
Deployment
Docker Compose
Application and database deployment
Selected
Tablet
Android tablet, 10" class
Room display and PIN input
Selected
Tablet software
Chrome/Chromium Kiosk Mode
Full-screen room interface
Selected
RFID / Access Controller
ZKTeco ProRF, 13.56 MHz MF/MIFARE configuration
MIFARE reader, access controller, network connectivity, relay
Proposed
Electric Lock
ZKTeco LM-2805 / LM-2802
Physical door locking mechanism
Candidate
Door Sensor
Magnetic door contact
Detect whether the door is open or closed
Required
Exit Button
ZKTeco EB102 or equivalent
Local door exit request
Candidate
Controller ↔ Server
Ethernet / TCP-IP
Communication over company LAN
Required
Reader ↔ Controller
RS-485 / OSDP, if separate reader is required
RFID reader communication
Conditional
Network
Company LAN, preferably dedicated VLAN
Internal communication
Selected
Server
Company-provided on-premise server
Runs Dockerized application and PostgreSQL
Selected
25.1 ZKTeco ProRF
| Area | Selected Device / Technology | Role | Status |
|---|---|---|---|
| Application framework | TanStack Start | Admin UI, tablet UI, server/API | Selected |
| Frontend | React + TypeScript | Admin and tablet interfaces | Selected |
| Database | PostgreSQL | Application data, bookings, credentials, audit logs | Selected |
| ORM | Drizzle ORM | Database access and type-safe queries | Proposed |
| Deployment | Docker Compose | Application and database deployment | Selected |
| Tablet | Android tablet, 10" class | Room display and PIN input | Selected |
| Tablet software | Chrome/Chromium Kiosk Mode | Full-screen room interface | Selected |
| RFID / Access Controller | ZKTeco ProRF, 13.56 MHz MF/MIFARE configuration | MIFARE reader, access controller, network connectivity, relay | Proposed |
| Electric Lock | ZKTeco LM-2805 / LM-2802 | Physical door locking mechanism | Candidate |
| Door Sensor | Magnetic door contact | Detect whether the door is open or closed | Required |
| Exit Button | ZKTeco EB102 or equivalent | Local door exit request | Candidate |
| Controller ↔ Server | Ethernet / TCP-IP | Communication over company LAN | Required |
| Reader ↔ Controller | RS-485 / OSDP, if separate reader is required | RFID reader communication | Conditional |
| Network | Company LAN, preferably dedicated VLAN | Internal communication | Selected |
| Server | Company-provided on-premise server | Runs Dockerized application and PostgreSQL | Selected |
Proposed device: ZKTeco ProRF with the 13.56 MHz MF/MIFARE reader configuration.
Official product page:
The ProRF is proposed because it can combine several functions required by the system:
- 13.56 MHz MF/MIFARE card support
- TCP/IP connectivity
- Access-control functionality
- Relay output for electric lock
- Door sensor input
- Exit-button input
The exact configuration must be confirmed with the distributor because the ProRF family may have different RFID-reader configurations.
25.2 Electric Lock
Candidate: ZKTeco LM-2805 / LM-2802 electromagnetic lock.
Official ZKTeco website:
The electric lock does not need to connect directly to the LAN.
The architecture is:
26. Why This Architecture
Centralized business logic
Meeting authorization lives in the application rather than being duplicated across tablets.
Hardware independence
The physical electric lock does not need to understand the application, HTTP, RFID, or the Internet.
Separation of responsibilities
Simple deployment
One application server can support multiple meeting rooms.
LAN-first
The system does not need cloud infrastructure for normal operation.
Expandable
Future versions can add:
- Employee self-service booking.
- VPN access.
- Calendar integration.
- Microsoft 365/Google Workspace integration.
- Notifications.
- Occupancy sensors.
- Usage analytics.
- Mobile administration.
- Multiple office locations.
without fundamentally changing the room-level architecture.
27. MVP Scope
Included
- Admin manages rooms.
- Admin manages employees.
- Admin creates meetings.
- Admin assigns attendees.
- Tablet displays meeting information.
- MIFARE card authentication.
- Meeting-based access authorization.
- PIN fallback.
- Electric door control.
- Access logging.
- Door status.
- Exit button.
- LAN-only operation.
- Docker deployment.
- PostgreSQL database.
Not included
- Public Internet access.
- Employee self-service booking.
- VPN booking.
- Calendar synchronization.
- Cloud infrastructure.
- Mobile application.
- Multi-company/multi-tenant architecture.
- Advanced analytics.
28. Open Questions / Validation Before Implementation
These must be resolved before purchasing hardware:
- ZKTeco integration
- Can our backend directly communicate with ProRF?
- Is an SDK/API available?
- Can we issue a remote unlock command?
- Can we receive real-time RFID/access events?
- Is ZKBioSecurity required?
- MIFARE compatibility
- Confirm the exact card technology used by the company.
- Confirm the selected ZKTeco configuration supports it.
- Door hardware
- What type of meeting-room doors are installed?
- Maglock or electric strike?
- What are the fire-safety requirements?
- What fail-safe/fail-secure behavior is required?
- Network
- Available VLAN/subnet.
- Static IP/DHCP reservation policy.
- Firewall rules.
- Required ports.
- Whether the access-control devices may communicate with the application server directly.
- Server
- Operating system.
- CPU/RAM/storage.
- Docker availability.
- Backup policy.
- UPS availability.
- Operational requirements
- What happens if the server is offline?
- What happens if the LAN is offline?
- What happens if the access controller is offline?
- Who administers the system?
- Who handles emergency access?
29. Final Baseline
The proposed baseline is:
Architecture status: Approved as the MVP baseline. Hardware status: Provisional. Primary remaining technical risk: Confirming the ZKTeco controller's third-party integration/API and remote-unlock capability before purchasing hardware. Primary physical validation: Confirming the appropriate electric-lock type and safety requirements for the actual meeting-room doors.