CBPOServices | IT Documentation

Biometrics System Architecture

Technical architecture and operational design for biometric terminals, the Python/Flask bridge service, local attendance storage, employee identity mapping, and the web portal.

Prepared By: Vio Manzanas System Owner: IT Department Document Version: v1.1.0 Last Updated: August 2026

1. System Architecture & Network Topology

The system uses separate paths for biometric attendance data and employee identity data. Physical biometric terminals communicate with a Python/Flask bridge service running on the internal spark host. The bridge retrieves attendance records from the terminals and persists them in a local SQLite database. The web portal accesses the bridge API through the configured Cloudflare Tunnel. Separately, the portal queries the Teams Directory Worker on Cloudflare to obtain employee records from Cloudflare D1.

Overall architecture
EMPLOYEE IDENTITY PATH ┌─────────────────────┐ HTTPS/REST ┌─────────────────────────┐ │ Biometrics Portal │ ──────────────────► │ Teams Directory Worker │ │ bio.html │ │ Cloudflare Workers │ └─────────┬───────────┘ └────────────┬────────────┘ │ │ │ ▼ │ ┌─────────────────┐ │ │ Cloudflare D1 │ │ │ agents table │ │ └─────────────────┘ │ │ HTTPS/REST ▼ ┌──────────────────────────┐ │ Cloudflare Tunnel / │ │ biometric-api domain │ └────────────┬─────────────┘ │ │ HTTP to local service ▼ ┌──────────────────────────┐ │ Python / Flask Bridge │ │ host: spark │ │ 10.0.70.10 / VLAN 70 │ │ port 5001 │ └────────────┬─────────────┘ │ ├──────────────────► attendance.db │ local SQLite │ │ ZK protocol / TCP 4370 ▼ ┌───────────────┐ │ Biometric │ │ Terminals │ │ VLAN 60 │ └───────────────┘ 192.168.10.230 192.168.10.231
Important separation: The biometric terminals do not communicate with Cloudflare directly. They communicate with the Python bridge over the internal network. Cloudflare Tunnel provides external HTTPS access to the local Flask API. The Teams Directory Worker is a separate Cloudflare service and accesses D1 independently.

2. Python Biometric Bridge Service

The biometric bridge is implemented in Python using Flask and the zk library. The application defines two physical biometric devices and exposes REST endpoints on local port 5001. CORS is enabled by the application to permit browser-based frontend access.

Device Configuration

DeviceIP AddressPortRole
Entrance Scanner 1192.168.10.230TCP 4370Physical biometric terminal
Entrance Scanner 2192.168.10.231TCP 4370Physical biometric terminal

Database Initialization

On application startup, init_db() creates the SQLite database file attendance.db if it does not already exist and creates the logs table. The database path is relative to the application's current working directory.

SQLite schema
attendance.db └── logs ├── id INTEGER PRIMARY KEY AUTOINCREMENT ├── device_ip TEXT ├── user_id TEXT ├── timestamp TEXT ├── status TEXT └── UNIQUE(device_ip, user_id, timestamp)

The unique constraint on device_ip, user_id, and timestamp, combined with INSERT OR IGNORE, prevents the same punch record from being inserted more than once for the same device, user, and timestamp.

Live Synchronization Endpoint: GET /api/get-logs

When requested, the endpoint loops through both configured scanners. For each device it creates a ZK connection with a four-second timeout, retrieves attendance records using get_attendance(), disconnects, and attempts to persist the returned records into SQLite. The endpoint then returns the retrieved records and device status as JSON.

Live synchronization flow
User requests live snapshot │ ▼ GET /api/get-logs │ ▼ Loop through configured devices │ ├──────────────► Scanner 1 (192.168.10.230:4370) │ └──────────────► Scanner 2 (192.168.10.231:4370) │ ▼ get_attendance() │ ▼ Raw attendance records │ ┌─────────┴─────────┐ ▼ ▼ SQLite INSERT JSON response OR IGNORE to frontend │ │ ▼ ▼ attendance.db Biometrics UI
Identity boundary: The Python service does not perform employee-name lookup. The attendance records contain the scanner's user_id, timestamp, status, and device context. Employee identity resolution is performed separately by the frontend using the Teams Directory data.

Historical Endpoint: GET /api/get-history

The historical endpoint reads records from the local SQLite logs table. If a date query parameter is supplied in YYYY-MM-DD format, the endpoint filters timestamps beginning with that date. Without a date parameter, it returns all stored records.

3. Cloudflare Tunnel & API Exposure

The local Flask service listens on port 5001 on the spark host. The configured Cloudflare Tunnel provides the external HTTPS route used by the web portal to reach that local service through biometric-api.cbposervices.com.

Internet / Protected Web Portal │ │ HTTPS ▼ biometric-api.cbposervices.com │ │ Cloudflare Tunnel ▼ spark / local network │ ▼ Flask application :5001
Scope of this document: The Python source confirms the Flask listener and local API behavior. Exact Cloudflare Tunnel ingress rules, Access policies, and TLS configuration are external deployment configuration and should be documented separately if required.

4. Teams Directory Worker & Employee Identity Mapping

The Biometrics frontend uses the Teams Directory Worker to retrieve employee directory records from Cloudflare D1. The directory provides the employee information needed to translate biometric numeric user_id/CID values into employee names.

Biometric attendance record │ │ user_id / CID ▼ Biometrics Portal │ │ directory lookup ▼ Teams Directory Worker │ ▼ Cloudflare D1 │ ▼ Employee record │ ▼ CID → employee name │ ▼ Display in Biometrics UI

The Teams API code reviewed for this architecture includes GET operations for employee records, dropdown options, and activity logs, plus a POST / operation that creates or updates an employee record and writes an activity log. It is therefore more accurate to describe the backend as supporting create/update operations, rather than calling it "full CRUD."

Current UI scope: The current bio.html interface is a biometric monitoring/reporting interface. It does not currently expose an Add Agent or Edit Agent form, even though the Teams API contains backend create/update functionality.

5. Frontend Application Flow

A. Page Initialization CURRENT

Open Biometrics page │ ▼ Request employee directory │ ▼ Build CID → employee-name mapping │ ▼ Load attendance data │ ▼ Resolve IDs against directory │ ▼ Render biometric logs

B. Live Snapshot CURRENT

Click "Pull Live Buffer Snapshot" │ ▼ GET /api/get-logs │ ▼ Flask bridge queries scanners │ ▼ Records saved to SQLite │ ▼ JSON returned to browser │ ▼ Logs displayed

C. Historical Review CURRENT

Select date / all history │ ▼ GET /api/get-history │ ▼ SQLite query │ ▼ Attendance records returned │ ▼ CID/name resolution │ ▼ Filtered results displayed

D. Employee Management BACKEND CAPABILITY

Management client / future UI │ ▼ POST / │ ▼ Teams Directory Worker │ ├── Create or update agents record │ └── Write activity_logs record │ ▼ Cloudflare D1

6. Network & Service Summary

ComponentLocationProtocol / PortTechnology / Purpose
Entrance Scanner 1192.168.10.230 / VLAN 60TCP 4370Biometric terminal
Entrance Scanner 2192.168.10.231 / VLAN 60TCP 4370Biometric terminal
Python Bridgespark / 10.0.70.10 / VLAN 70Flask HTTP :5001Python / Flask / ZK / SQLite
Attendance DatabaseLocal to Python bridgeSQLite fileHistorical attendance persistence
Biometric API Gatewaybiometric-api.cbposervices.comHTTPS via tunnelCloudflare Tunnel ingress
Teams Directory WorkerCloudflare EdgeHTTPS / RESTEmployee directory API
Cloudflare D1CloudflareWorker bindingEmployee directory storage

7. Current Functionality & Scope

CapabilityStatusNotes
Scanner communicationImplementedPython bridge queries both configured terminals over TCP 4370.
Live attendance synchronizationImplementedLive endpoint retrieves scanner records and stores them in SQLite.
Historical attendanceImplementedHistory endpoint reads local SQLite records, optionally filtered by date.
Employee-name resolutionImplementedDirectory data is used by the frontend to resolve biometric IDs.
Biometric monitoring UIImplementedCurrent page focuses on viewing, filtering, and reviewing attendance records.
Agent create/update APIBackend CapabilityTeams API supports creation/update and activity logging through POST.
Agent management UI in bio.htmlNot Current UINo Add/Edit Agent workflow is exposed on the current Biometrics page.

8. Operational Notes

  • Service startup: The Python application calls init_db() before starting Flask when executed directly.
  • Windows service deployment: If the application is managed through NSSM on spark, NSSM is a deployment/runtime management layer rather than part of the Python application itself.
  • Scanner connectivity: The bridge uses a four-second ZK connection timeout for each configured scanner.
  • Database location: attendance.db is a relative path in the Python source. Its actual filesystem location depends on the process working directory.
  • CORS: The current Python application enables Flask-CORS globally. Production access control is therefore dependent on the surrounding network/tunnel/security configuration as well as the application itself.

9. Architecture Boundaries & Assumptions

  • The Python bridge is responsible for scanner communication and attendance persistence; it does not own employee profile information.
  • Employee identity data is maintained separately through the Teams Directory Worker and Cloudflare D1.
  • The biometric API returns machine-readable attendance data; the portal is responsible for presentation and identity resolution.
  • The Cloudflare Tunnel configuration is outside the Python source and should not be inferred beyond the known public API route.
  • The current documentation describes the implementation reviewed in August 2026. Future management UI or additional endpoints should be reflected in a subsequent revision.

10. Document Revision History

VersionDatePrepared BySummary
v1.1.02026-08-15Vio ManzanasUpdated system architecture, data flows, component relationships, and implementation details.
v1.0.02026-08-14Vio ManzanasInitial biometrics architecture documentation.