Skip to content

Commit 6305069

Browse files
authored
Update migration files and refactor tests for audit population (#49)
1 parent b4cdcf9 commit 6305069

39 files changed

Lines changed: 5087 additions & 2486 deletions

.codacy.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
include_paths:
2-
- "backend/**"
3-
- "migrations/**"
1+
include_paths: ["backend/**"]
42
exclude_paths:
53
- ".github/**"
6-
- "backend/tests/**"
4+
- "**/tests/**"
5+
- "migrations/**"

.github/workflows/code_test.yml

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,6 @@ jobs:
7676
test_migrations:
7777
runs-on: ubuntu-latest
7878

79-
permissions:
80-
id-token: write
81-
contents: read
82-
8379
steps:
8480
- name: Checkout Repository
8581
uses: actions/checkout@v6
@@ -88,12 +84,4 @@ jobs:
8884

8985
- name: Migration tests
9086
run: |
91-
uv run --with coverage,pytest-cov \
92-
python -m pytest migrations/test_migrations.py -n auto --cov --cov-report=xml
93-
94-
- name: Upload coverage to Codecov
95-
uses: codecov/codecov-action@v5
96-
with:
97-
fail_ci_if_error: true
98-
use_oidc: true
99-
verbose: true
87+
uv run migrations/run_tests.py -n auto

.github/workflows/sonarcloud.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ permissions:
44
contents: read
55
on:
66
push:
7-
branches:
8-
- main
7+
branches: [ main ]
98
pull_request:
10-
types: [opened, synchronize, reopened]
9+
branches: [ main ]
1110

1211
jobs:
1312
sonarqube:

backend/__init__.py

Whitespace-only changes.

migrations/01_roles.sql

Lines changed: 113 additions & 102 deletions
Large diffs are not rendered by default.

migrations/02_reference.sql

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,24 @@
4949
-- (e.g. license_status_code = 'ACTIVE' is readable without a
5050
-- join). New enum values are added by INSERT only — no UPDATE
5151
-- or DELETE of existing rows is ever permitted.
52+
--
53+
-- ACTION CODE DESIGN
54+
-- Action codes in reference."actions" are intentionally
55+
-- resource-agnostic. The resource type and ID are captured
56+
-- in audit junction tables (audit_log_licenses,
57+
-- audit_log_sessions, audit_log_vendor_actors). A REVOKED
58+
-- entry joined to audit_log_licenses means a license was
59+
-- revoked; joined to audit_log_sessions means a session was
60+
-- revoked. This allows new resource types to be added in
61+
-- future without introducing new action codes for common verbs.
5262
-- ============================================================
5363

5464
BEGIN;
5565

5666
-- Switch to the schema owner so that default privileges defined
5767
-- in 01_roles.sql for reference_owner apply to all objects
5868
-- created in this transaction.
59-
SET LOCAL ROLE reference_owner;
69+
SET LOCAL ROLE "reference_owner";
6070

6171
-- ============================================================
6272
-- reference."license_statuses"
@@ -68,7 +78,7 @@ SET LOCAL ROLE reference_owner;
6878
-- ============================================================
6979

7080
DO $$ BEGIN
71-
CREATE TABLE reference."license_statuses" (
81+
CREATE TABLE "reference"."license_statuses" (
7282
"code" TEXT PRIMARY KEY,
7383
"description" TEXT NOT NULL
7484
);
@@ -77,11 +87,11 @@ EXCEPTION WHEN duplicate_table THEN
7787
END $$;
7888

7989
-- COMMENT ON is idempotent and intentionally outside the DO block.
80-
COMMENT ON TABLE reference."license_statuses" IS 'Lookup table for license lifecycle states. EXPIRED is intentionally omitted: expiry is a derived state computed at query time from app."licenses"."expires_at". Storing it redundantly would risk inconsistency.';
81-
COMMENT ON COLUMN reference."license_statuses"."code" IS 'Machine-readable status code (PK). Self-documents FK references in app."licenses". Examples: ACTIVE, REVOKED.';
82-
COMMENT ON COLUMN reference."license_statuses"."description" IS 'Human-readable explanation of this license state for developers and operators.';
90+
COMMENT ON TABLE "reference"."license_statuses" IS 'Lookup table for license lifecycle states. EXPIRED is intentionally omitted: expiry is a derived state computed at query time from "app"."licenses"."expires_at". Storing it redundantly would risk inconsistency.';
91+
COMMENT ON COLUMN "reference"."license_statuses"."code" IS 'Machine-readable status code (PK). Self-documents FK references in "app"."licenses". Examples: ACTIVE, REVOKED.';
92+
COMMENT ON COLUMN "reference"."license_statuses"."description" IS 'Human-readable explanation of this license state for developers and operators.';
8393

84-
INSERT INTO reference."license_statuses" ("code", "description")
94+
INSERT INTO "reference"."license_statuses" ("code", "description")
8595
VALUES
8696
('ACTIVE', 'License is valid and can be activated by a customer device.'),
8797
('REVOKED', 'License was manually revoked by the vendor; no further activations or heartbeats are permitted.')
@@ -96,19 +106,19 @@ ON CONFLICT ("code") DO NOTHING;
96106
-- ============================================================
97107

98108
DO $$ BEGIN
99-
CREATE TABLE reference."session_statuses" (
109+
CREATE TABLE "reference"."session_statuses" (
100110
"code" TEXT PRIMARY KEY,
101111
"description" TEXT NOT NULL
102112
);
103113
EXCEPTION WHEN duplicate_table THEN
104114
RAISE NOTICE 'table reference."session_statuses" already exists, skipping';
105115
END $$;
106116

107-
COMMENT ON TABLE reference."session_statuses" IS 'Lookup table for session lifecycle states. Derived states (grace period exceeded, license expired) are computed at query time, not stored.';
108-
COMMENT ON COLUMN reference."session_statuses"."code" IS 'Machine-readable status code (PK). Values: ACTIVE, REVOKED, ZOMBIE, CLEANUP.';
109-
COMMENT ON COLUMN reference."session_statuses"."description" IS 'Human-readable explanation of this session state for developers and operators.';
117+
COMMENT ON TABLE "reference"."session_statuses" IS 'Lookup table for session lifecycle states. Derived states (grace period exceeded, license expired) are computed at query time, not stored.';
118+
COMMENT ON COLUMN "reference"."session_statuses"."code" IS 'Machine-readable status code (PK). Values: ACTIVE, REVOKED, ZOMBIE, CLEANUP.';
119+
COMMENT ON COLUMN "reference"."session_statuses"."description" IS 'Human-readable explanation of this session state for developers and operators.';
110120

111-
INSERT INTO reference."session_statuses" ("code", "description")
121+
INSERT INTO "reference"."session_statuses" ("code", "description")
112122
VALUES
113123
('ACTIVE', 'Session is running and receiving heartbeats normally.'),
114124
('REVOKED', 'Session was explicitly terminated by a vendor action or an automated system process.'),
@@ -124,19 +134,19 @@ ON CONFLICT ("code") DO NOTHING;
124134
-- ============================================================
125135

126136
DO $$ BEGIN
127-
CREATE TABLE reference."heartbeat_resp_statuses" (
137+
CREATE TABLE "reference"."heartbeat_resp_statuses" (
128138
"code" TEXT PRIMARY KEY,
129139
"description" TEXT NOT NULL
130140
);
131141
EXCEPTION WHEN duplicate_table THEN
132142
RAISE NOTICE 'table reference."heartbeat_resp_statuses" already exists, skipping';
133143
END $$;
134144

135-
COMMENT ON TABLE reference."heartbeat_resp_statuses" IS 'Lookup table for heartbeat response codes returned by the server to the SDK. The server selects a code based on current license and session state; the SDK takes a mandatory action based on the code received.';
136-
COMMENT ON COLUMN reference."heartbeat_resp_statuses"."code" IS 'Machine-readable response code (PK). Values: CONTINUE, REFRESH, REVOKED, EXPIRED, ERROR.';
137-
COMMENT ON COLUMN reference."heartbeat_resp_statuses"."description" IS 'Human-readable description of the response code and the SDK action it mandates.';
145+
COMMENT ON TABLE "reference"."heartbeat_resp_statuses" IS 'Lookup table for heartbeat response codes returned by the server to the SDK. The server selects a code based on current license and session state; the SDK takes a mandatory action based on the code received.';
146+
COMMENT ON COLUMN "reference"."heartbeat_resp_statuses"."code" IS 'Machine-readable response code (PK). Values: CONTINUE, REFRESH, REVOKED, EXPIRED, ERROR.';
147+
COMMENT ON COLUMN "reference"."heartbeat_resp_statuses"."description" IS 'Human-readable description of the response code and the SDK action it mandates.';
138148

139-
INSERT INTO reference."heartbeat_resp_statuses" ("code", "description")
149+
INSERT INTO "reference"."heartbeat_resp_statuses" ("code", "description")
140150
VALUES
141151
('CONTINUE', 'License is valid and the session is healthy. SDK should continue normal protected operation with no state change.'),
142152
('REFRESH', 'The vendor has modified the license configuration since the last heartbeat (e.g. expiry extended, max_grace_secs changed, metadata updated). SDK must re-fetch the current license state and apply it before continuing.'),
@@ -154,19 +164,19 @@ ON CONFLICT ("code") DO NOTHING;
154164
-- ============================================================
155165

156166
DO $$ BEGIN
157-
CREATE TABLE reference."error_codes" (
167+
CREATE TABLE "reference"."error_codes" (
158168
"code" TEXT PRIMARY KEY,
159169
"description" TEXT NOT NULL
160170
);
161171
EXCEPTION WHEN duplicate_table THEN
162172
RAISE NOTICE 'table reference."error_codes" already exists, skipping';
163173
END $$;
164174

165-
COMMENT ON TABLE reference."error_codes" IS 'Canonical lookup table for business error codes used in API responses and SDK error handling. HTTP status code mapping is handled exclusively in application code and is decoupled from this table.';
166-
COMMENT ON COLUMN reference."error_codes"."code" IS 'Machine-readable error code constant (PK). Referenced by API responses, SDK error handlers, and log entries.';
167-
COMMENT ON COLUMN reference."error_codes"."description" IS 'Human-readable explanation of the error condition for developers and operators.';
175+
COMMENT ON TABLE "reference"."error_codes" IS 'Canonical lookup table for business error codes used in API responses and SDK error handling. HTTP status code mapping is handled exclusively in application code and is decoupled from this table.';
176+
COMMENT ON COLUMN "reference"."error_codes"."code" IS 'Machine-readable error code constant (PK). Referenced by API responses, SDK error handlers, and log entries.';
177+
COMMENT ON COLUMN "reference"."error_codes"."description" IS 'Human-readable explanation of the error condition for developers and operators.';
168178

169-
INSERT INTO reference."error_codes" ("code", "description")
179+
INSERT INTO "reference"."error_codes" ("code", "description")
170180
VALUES
171181
('INVALID_CREDENTIALS', 'Authentication failed due to incorrect email or password.'),
172182
('INVALID_TOKEN', 'JWT access token is missing, malformed, or has expired.'),
@@ -185,41 +195,52 @@ ON CONFLICT ("code") DO NOTHING;
185195
-- ============================================================
186196
-- reference."actions"
187197
-- ============================================================
188-
-- Auditable action verbs recorded in audit."auditLogs".
198+
-- Auditable action verbs recorded in audit."audit_logs".
189199
-- Codes are broadly resource-agnostic; the affected resource
190200
-- is captured in audit junction tables. This allows new
191-
-- resource types to be added without modifying audit."auditLogs".
192-
-- Exception: HEARTBEAT_ERROR is heartbeat-specific by nature
193-
-- and is an intentional exception to the resource-agnostic
194-
-- principle — documented here to prevent future confusion.
201+
-- resource types to be added without modifying audit."audit_logs".
202+
-- Exceptions to the resource-agnostic principle (documented
203+
-- here to prevent future confusion):
204+
-- HEARTBEAT_ERROR — heartbeat-specific by nature
205+
-- PASSWORD_CHANGED — vendor-specific by nature
206+
-- TOKEN_ROTATED — session-specific by nature
207+
-- TOKEN_REFRESHED — vendor auth flow specific
208+
-- ACTIVATED — session creation via license activation
209+
-- LOGIN_SUCCESS — vendor auth flow specific
210+
-- LOGIN_FAILED — vendor auth flow specific
211+
-- CLEANED — session CLEANUP transition, system-driven
195212
-- ============================================================
196213

197214
DO $$ BEGIN
198-
CREATE TABLE reference."actions" (
215+
CREATE TABLE "reference"."actions" (
199216
"code" TEXT PRIMARY KEY,
200217
"description" TEXT NOT NULL
201218
);
202219
EXCEPTION WHEN duplicate_table THEN
203220
RAISE NOTICE 'table reference."actions" already exists, skipping';
204221
END $$;
205222

206-
COMMENT ON TABLE reference."actions" IS 'Lookup table for auditable action verbs recorded in audit."auditLogs". Codes are broadly resource-agnostic; the affected resource is captured in audit junction tables (audit."auditLogLicenses", audit."auditLogSessions", etc.). HEARTBEAT_ERROR is an intentional exception: it is heartbeat-specific by nature.';
207-
COMMENT ON COLUMN reference."actions"."code" IS 'Machine-readable action verb (PK). Examples: CREATED, MODIFIED, REVOKED, DELETED.';
208-
COMMENT ON COLUMN reference."actions"."description" IS 'Human-readable description of what this action represents in the system.';
223+
COMMENT ON TABLE "reference"."actions" IS 'Lookup table for auditable action verbs recorded in "audit"."audit_logs". Codes are broadly resource-agnostic; the affected resource is captured in audit junction tables ("audit"."audit_log_licenses", "audit"."audit_log_sessions", etc.). Exceptions (HEARTBEAT_ERROR, PASSWORD_CHANGED, TOKEN_ROTATED, etc.) are heartbeat- or auth-flow-specific by nature and are documented in the migration file header.';
224+
COMMENT ON COLUMN "reference"."actions"."code" IS 'Machine-readable action verb (PK). Examples: CREATED, MODIFIED, REVOKED, DELETED.';
225+
COMMENT ON COLUMN "reference"."actions"."description" IS 'Human-readable description of what this action represents in the system.';
209226

210-
INSERT INTO reference."actions" ("code", "description")
227+
INSERT INTO "reference"."actions" ("code", "description")
211228
VALUES
212-
('SIGNUP', 'A new actor account was registered on the platform.'),
213-
('LOGIN_SUCCESS', 'An actor successfully authenticated and received an access token.'),
214-
('LOGIN_FAILED', 'An actor authentication attempt failed due to invalid credentials.'),
215-
('TOKEN_REFRESHED', 'An actor obtained a new access token using a valid refresh token.'),
216-
('CREATED', 'A new resource was created.'),
217-
('MODIFIED', 'An existing resource was modified.'),
218-
('REVOKED', 'A resource was revoked by an authorised actor.'),
219-
('EXPIRED', 'A resource was transitioned to an expired state by the system.'),
220-
('ACTIVATED', 'A new session was created via a successful license key activation.'),
221-
('HEARTBEAT_ERROR', 'A heartbeat was received but produced a non-CONTINUE response; the event is recorded in app."heartbeats" for audit continuity.'),
222-
('DELETED', 'A resource was soft-deleted.')
229+
('SIGNUP', 'A new vendor account was registered on the platform.'),
230+
('LOGIN_SUCCESS', 'A vendor successfully authenticated and received an access token.'),
231+
('LOGIN_FAILED', 'A vendor authentication attempt failed due to invalid credentials.'),
232+
('TOKEN_REFRESHED', 'A vendor obtained a new access token using a valid refresh token.'),
233+
('CREATED', 'A new resource was created.'),
234+
('MODIFIED', 'An existing resource had one or more fields modified.'),
235+
('CONFIG_UPDATED', 'Structural policy configuration of a resource was changed (e.g. expires_at, max_grace_secs, max_sessions).'),
236+
('REVOKED', 'A resource was revoked by an authorised actor.'),
237+
('EXPIRED', 'A resource was transitioned to an expired state by the system.'),
238+
('ACTIVATED', 'A new session was created via a successful license key activation.'),
239+
('TOKEN_ROTATED', 'A session bearer token was rotated. Hash values are never recorded.'),
240+
('HEARTBEAT_ERROR', 'A heartbeat was received but produced a non-CONTINUE response; the event is recorded in app."heartbeats" for audit continuity.'),
241+
('DELETED', 'A resource was soft-deleted.'),
242+
('PASSWORD_CHANGED', 'A vendor account password was changed. Hash values are never recorded.'),
243+
('CLEANED', 'A session was transitioned to CLEANUP status by the system cleanup job.')
223244
ON CONFLICT ("code") DO NOTHING;
224245

225246
COMMIT;

0 commit comments

Comments
 (0)