MILLIONHARI LLC (dba PoliceNarratives.ai)
Effective Date: April 8, 2026 | Version 1.0
This document is the public engineering reference for the Police Narratives AI platform. It is the document referenced by the MILLIONHARI LLC Secure Development Policy as the "Engineering Documentation Link." It describes the high-level architecture, environments, secure-by-design principles, privacy-by-design principles, coding standards, and security testing practices that govern engineering work at MILLIONHARI LLC.
Police Narratives AI is an AI-backed police reporting platform that generates professional incident reports from audio transcription and AI-assisted narrative generation. The platform is delivered as a monorepo composed of three applications and a set of supporting serverless functions:
client/) — React (Create React App) + TypeScript,
TipTap rich-text editor, TailwindCSS, and DaisyUI.
server/) — Express.js + TypeScript, Passport.js
authentication, Redis-backed sessions, Drizzle ORM over PostgreSQL.
PoliceNarrativesMobile/) — React Native via Expo.
Production runs in AWS GovCloud (us-gov-west-1). The platform is built around the
following services:
PoliceNarrativesAIProd cluster.
MILLIONHARI LLC maintains three logically segregated environments covering the entire system development life cycle:
Customer (Confidential) data must never be copied into development or test environments without the explicit written permission of the data owner and the Founder, in accordance with the Secure Development Policy.
The following principles, drawn from the Secure Development Policy, are applied to every engineering decision. They are non-negotiable and reviewers verify them during code review.
Endpoints, IAM permissions, and S3 bucket policies are scoped to the minimum required. The interaction audio bucket has no S3 event notifications because Lambdas are invoked directly by the server, eliminating an unnecessary public trigger.
Routes default to authenticated and authorized; opt-in is required to expose anything publicly. The Helmet middleware is enabled system-wide. CJIS session limits (12-hour maximum, 30-minute inactivity timeout) are enforced server-side.
Officers see only their own cases; Records-role users see all agency cases; agency admins manage their
own agency. Access checks are enforced server-side in caseAccess rather than relying on
the client to hide UI.
Authentication, authorization, MFA, rate limiting, Helmet headers, and input validation all run independently. A failure in any single layer does not expose data, because the next layer must also authorize the request.
Error paths default to denial. When transcription processing is cancelled, the server atomically aborts in-progress S3 multipart uploads, deletes completed files, cancels Amazon Transcribe jobs, and marks case files as failed before discarding the case. No state is left in a partially-trusted condition.
Lambda callbacks (transcription complete, narrative complete) are treated as untrusted input: case identifiers are re-validated, the server checks that the case still exists and has not been discarded, and the file completion guard prevents wasted Bedrock invocations on cancelled cases.
Development, review, and deployment are not performed end-to-end by a single individual. The pull-request approval requirement and the dual-auth admin model (individual users vs. agency admins) both embody this principle.
Security controls are documented and reviewable. The protection of the system depends on cryptographic keys and access controls, not on the secrecy of paths, parameter names, or API shapes.
Security primitives are centralized: a single MFA service, a single session-timeout middleware, a single case-access helper. Engineers reuse these rather than implementing parallel logic.
Security findings are fixed at the root cause, regression-tested, and tracked through the standard change-control process. Patches that materially impact security are deployed within 90 days of discovery, in line with the Secure Development Policy.
Privacy considerations are evaluated during design — before any code is written — rather than as a remediation step.
New features default to the most privacy-preserving setting. Audio retention, narrative content, and case data are never shared outside the agency that owns them without an explicit user action.
Multi-tenancy, role-based access control, and agency scoping are first-class concepts in the data model rather than bolt-on filters.
Privacy and usability are designed together. The "Keep original video file" toggle, video audio extraction, and the cancellation flow each preserve full feature value while minimizing the data the system retains.
Audio is transmitted over TLS, stored in private S3 buckets, and processed by Lambdas under scoped IAM roles. Stale uploads are cleaned up by hourly cron jobs.
The Privacy Policy and this Engineering Documentation are public. Customers can see what is collected, how it is processed, and the third-party AI service providers that participate.
Users may review, update, or delete their data through the data subject access request workflow described in the Privacy Policy.
Police Narratives AI uses a dual-authentication model, both based on Passport.js with Redis-backed sessions:
/login with email/password or OAuth
providers (Google, Apple).
/agency/login and may use SAML
2.0 or OIDC single-sign-on configured per agency.
Multi-factor authentication is configurable per agency for CJIS compliance and supports TOTP authenticator apps, WebAuthn (Touch ID, Face ID, security keys), and Email OTP. Trusted-device support reduces re-authentication friction within a configurable window. Backup codes are issued at MFA enrollment and are stored hashed.
Server-side session enforcement caps sessions at 12 hours and inactivity at 30 minutes. Routes that handle protected data are guarded by middleware that rejects requests from non-MFA-verified sessions.
Authorization is role-based:
.env.sample file documents required keys without
values.
Audio is processed asynchronously through a pipeline of AWS Lambda functions. The pipeline is split into two flows depending on the audio type:
Failure handling is explicit: Lambdas report errors back to the API server, which marks the affected case files and cases as failed. Stale uploads are cleaned up by an hourly cron job. Cancellation is atomic and removes all in-flight S3 objects, multipart uploads, and Transcribe jobs associated with the case.
server/src/db/schema.ts using Drizzle ORM. The schema is the
single source of truth and is auto-synced to the client and mobile applications during migration.
yarn generate to produce a new migration
file. Once committed and merged, migration files are immutable; corrections land as new migrations.
yarn migrate. The yarn push command is reserved
for development use and is not run against production.
yarn audit findings are triaged during code review.
yarn.lock to
ensure reproducible builds.
Software developers complete secure-development training appropriate to their role at least annually. Training covers, at minimum, the prevention of authorization bypass attacks, insecure session IDs, injection attacks, cross-site scripting, cross-site request forgery, and the use of vulnerable libraries.
Questions about this Engineering Documentation should be sent to support@policenarratives.ai.