Ab/initial data model work - add z9/open and z9/flex community#22
Open
z9security wants to merge 32 commits into
Open
Ab/initial data model work - add z9/open and z9/flex community#22z9security wants to merge 32 commits into
z9security wants to merge 32 commits into
Conversation
…ture - Fix broken FK: credential_format_parity_bit_ranges now references credential_format_parity_bits (was pointing to nonexistent table) - Add has_many associations to all parent models (Building, Sector, AccessController, EntryWay, Group, Person, CredentialType, etc.) - Fix Sector parent to be optional with self-referential children - Add presence validations on name fields across all named models - Set up API controller base class (ActionController::API with auth hook) - Add /api/health endpoint with integration test - Add Z9/Flex Community API integration plan document - Update .ruby-version to 3.2.9 (matching installed rbenv version) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- POST /authenticate accepts {username, password, apiClientType}
- Returns {authenticated, sessionToken, softwareVersion, apiVersion,
timeZone, softwareVersionTimestamp} per swagger AuthenticateResult
- Failed auth returns {authenticated: false} (no 401, matches swagger)
- Auth enforcement via sessionToken header (swagger APIKeyAuth scheme)
on all Api::BaseController endpoints, returns 401 for missing/expired
- User model with bcrypt has_secure_password, unique username
- ApiSession model with auto-generated token, expiry, active scope
- Enable bcrypt gem
- 23 tests, 50 assertions (6 User, 8 ApiSession, 6 auth integration,
3 auth enforcement)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- GET /controller/list with DevListResponse pagination (offset, max, count)
- POST /controller/save creates AccessController, returns {instance: Dev}
- POST /controller/update/{id} by unid (integer) or uuid (string)
- POST /controller/delete/{id} by unid or uuid
- ControllerTranslator maps AccessController <-> Flex Dev JSON (devType=1,
ObjRefs for sector parent and entry_way children)
- Add uuid column to access_controllers with auto-generation
- All endpoints enforce sessionToken auth (401 without)
- 47 tests, 104 assertions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- GET/POST /door/* endpoints (EntryWay, devType=5) - GET/POST /credReader/* endpoints (Reader, devType=4) - GET/POST /sensor/* endpoints (Sensor, devType=2) - DoorTranslator, CredReaderTranslator, SensorTranslator - Extract HasUuid concern (shared by 4 models) - Extract DevTranslatorBase with shared obj_ref, base_dev_fields - Extract find_by_id_or_uuid and paginate into BaseController - Add uuid column to entry_ways, readers, sensors - 80 tests, 181 assertions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Unify AccessController, EntryWay, Reader, Sensor into a single devices table using Rails STI (IoController, Door, CredReader, Sensor < Device). This gives all device types a shared ID space matching the Z9/Flex Dev type hierarchy. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…wagger Add Flex fields (name, uuid, enabled, effective, expires, cardPin JSON) to credentials table and (name, uuid, priority, cardPinTemplate JSON) to credential_types table. Make person_id and credential_type_id nullable since Flex Cred doesn't require them. Add translators, API controllers, routes, and 59 new tests (149 total, all passing). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…yout CRUD Add card data format definitions (Wiegand bit encoding) and data layout endpoints per Z9/Flex Community swagger. BinaryFormat stores polymorphic elements array (Static/Parity/Field subtypes) as JSON column on credential_formats. BasicDataLayout references a DataFormat via ObjRef. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add DoorAccessPriv endpoints (list/save/update/delete) mapped to AccessRuleSet model. Elements stored in a proper join table (door_access_priv_elements) with FK references to access_rule_sets and devices, rather than a JSON column. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dule wiring Add Schedule, ScheduleElement, HolidayType, HolidayCalendar, Holiday models with join tables for HolType references. SchedTranslator maps day-of-week booleans to/from Flex integer arrays. Wire schedule ObjRef into DoorAccessPrivElement's schedRestriction (was hardcoded nil). 383 tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Event model with JSON columns for snapshot refs (evtDevRef,
evtControllerRef, evtCredRef, evtSchedRef, evtModifiers). Implement
GET /evt/list (with order asc/desc, pagination) and GET /evt/show/{id}.
No save/update/delete -- events are read-only. 407 tests pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ands Add Actuator (devType 3) and NodeDev (devType 0) STI device types with full CRUD endpoints. Add EncryptionKey model/table for db-based keystore with CRUD. Add doorModeChange and doorMomentaryUnlock command endpoints (GET, resolve device by unid/uuid). 467 tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements session logout per swagger spec. Requires valid sessionToken, destroys the ApiSession, and invalidates the token. 470 tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add 13 swagger Dev fields to devices table (address, port, devMod, devPlatform, devUse, externalId, timeZone, etc.) - Update DevTranslatorBase with all Dev fields in to_flex/from_flex, plus translator_for() and class_for_dev_type() dispatch methods - Add polymorphic /dev/* endpoints (list/save/update/delete) using devType discriminator to route to correct STI subclass and translator - Replace boilerplate README with project docs and full gap TODO list - 514 tests passing (44 new) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…chestrator - Add SpCoreServer (lib/spcore_server.rb): protobuf TCP server speaking Z9 Open Community Protocol with custom framing (magic + length + body) - Add DbChangeBuilder (lib/db_change_builder.rb): serializes Rails models to protobuf DbChange messages for sending to Aporta - Add proto bindings (lib/proto/): Ruby protobuf files generated from z9open-community v1.0.13 tag matching Aporta's NuGet package - Add E2E rake orchestrator (lib/tasks/e2e.rake): starts PD sim, SpCoreServer, and Aporta, sends config via DbChange, simulates card reads, verifies ACCESS_GRANTED/DENIED events through the full pipeline - Add unit tests for SpCoreServer and DbChangeBuilder - Add google-protobuf gem dependency - Update README with E2E architecture docs and test commands Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CredPrivBinding: migration, model, translator (to_flex/save_priv_bindings), controller (save/update), and DbChangeBuilder proto serialization. Binds credentials to access rule sets with optional schedule restriction and precision door access. SpCoreServer: auto-sync lifecycle (builds full sync from DB via DbChangeBuilder on Aporta connect), event persistence to Event table, proto enum resolution, and db_change_modifier callback for API gaps. E2E test rewritten to exercise the full pipeline: REST API creates all entities -> DbChangeBuilder serializes to proto -> SpCoreServer auto-syncs to Aporta -> card swipe -> access decision events flow back -> persisted to DB -> verified via /evt/list REST API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s done E2E test flow now documents the actual pipeline: REST API creates entities, SpCoreServer auto-syncs via DbChangeBuilder, events verified via /evt/list. CredReaderConfig TODO notes the db_change_modifier workaround. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add dev_config JSON column to devices table. Implement config storage, REST API serialization, and proto serialization for ControllerConfig, CredReaderConfig (+ commType, tamperType, ledType, serialPortAddress), SensorConfig (+ invert), ActuatorConfig (+ invert), and NodeDevConfig. Remove E2E db_change_modifier workaround -- pipeline is now 100% clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add door_access_modifiers JSON column to credentials. Implement storage, REST API serialization, and proto serialization for DoorAccessModifiers. Move DoorConfig to upstream schema gaps section in README alongside Hol. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both element_to_flex methods now emit unid: el.id in their output, matching the swagger schema for DoorAccessPrivElement and SchedElement. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tocol externalId was missing from the AccessRuleSet model and translator. kind, frequency, and protocol on CredentialType were not in the community swagger spec and have been removed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces record.class.name with FlexTypeNames.for(record) in all obj_ref methods. Maps: IoController->Controller, Schedule->Sched, CredentialType->CredTemplate, HolidayType->HolType, HolidayCalendar->HolCal, CredentialFormat->DataFormat, AccessRuleSet->DoorAccessPriv. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hol entries ARE in the community DbChange proto (fields 155-157). The gap is in real-bs DbChangeBuilder, not upstream. Corrected the README and the misleading comment in db_change_builder.rb. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Individual holidays (Hol) are now serialized into DbChange for download to Aporta. Includes date, holTypesUnid, holCalUnid, allHolTypes, numDays, repeat, numYearsRepeat, preserveSchedDay. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…evConfig; consolidate migrations Serve version (default 0), tag, and commFamily across all translator to_flex/from_flex methods. DevConfig subtypes now include unid (device id) and version. Optimistic locking behavior is a separate TODO. Consolidate 34 incremental migrations into a single create_all_tables migration since this code has never been deployed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename version_counter to lock_version across migration, schema, and all translators. Rails automatically increments lock_version on update and raises StaleObjectError when the WHERE clause misses. BaseController rescue_from returns 409 Conflict on stale writes. update_with_lock helper sets lock_version from client's version field before update, matching Hibernate @Version semantics. All 16 controller update actions use update_with_lock. Updates without a version field skip the locking check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add lock_version and tag to all 10 DbChangeBuilder proto methods (Dev, Cred, CredTemplate, DataFormat, DataLayout, Priv, Sched, HolType, Hol, HolCal). Remove the now-unused db_change_modifier callback infrastructure from SpCoreServer -- DevConfig is properly implemented via the API so the OSDP patch workaround is no longer needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…oints, DevStateRecord, externalDevMod
- Implement DoorConfig: full translator, DbChangeBuilder proto serialization with DoorMode/DoorModeStaticState
- Add show/{id} GET endpoints for all 20 entity types (19 new + evt already existed)
- Add DevStateRecord list endpoint (read-only projection from Device table)
- Add Dev.externalDevModText and Dev.externalDevModId fields (migration + translator + proto)
- Update README: 102 of 102 swagger endpoints implemented
684 tests, 0 failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Config Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
commFamily was removed from the community swagger (the CommFamily enum was never part of the community profile). Remove it from base_dev_fields and base_from_flex; leave the DB column in place. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…olderType Replace Group model with CredHolderType (with uuid, version, tag) to align with the Z9/Flex community profile. Replace Person's metadata JSON column with custom_text_0 through custom_text_7 string columns matching CustomData. Add uuid, lock_version, tag, enabled to Person. Make cred_holder_type FK optional. New endpoints: credHolder (list/show/save/update/delete) and credHolderType (list/show/save/update/delete). CredHolderTranslator maps Person to Flex CredHolder format including emails/phones as arrays and customData. All 736 tests pass including E2E. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.