Product architecture

Public records, transformed into structured civic action.

CivicLens ingests structured payloads from third-party content feeds, maps them to geographic entities, and guides users through six escalating engagement levels.

Core data flow

Content Feed
Third-party payloads
Rules Engine
Map · Classify · Route
Student View
Personalized records
Step 1 — Ingest

Schema-versioned payload

Each record carries entity_id, jurisdiction, category, severity, and supporting refs.

Step 2 — Resolve

State + ZIP → entities

State is the primary filter. ZIP narrows. ZIP alone is never sufficient.

Step 3 — Personalize

Match user interests

Records filtered by interests + jurisdiction, ordered by relevance and severity.

Rules engine

function classify(payload) {
  // 1. Jurisdiction lookup (state required)
  const entity = oversight_refs.find({ state: payload.state, zip: payload.zip });
  if (!entity) return route("unmapped_queue");

  // 2. Severity by keyword + impact metrics
  const severity = scoreSeverity(payload.body, payload.metrics);

  // 3. Category routing
  const category = matchCategory(payload.tags, taxonomy);

  // 4. Engagement template binding
  const templates = action_templates.where({ active: true, level: { lte: 6 } });

  return { entity, severity, category, templates, status: "open" };
}

Six engagement levels

1
Read

View record summary

+10
2
Share

Amplify socially

+25
3
Respond

Public comment

+75
4
Request

File records request

+150
5
Evidence

Upload documents

+250
6
Attend

Show up in person

+500

Database architecture

Six main tables, UUID primary keys, row-level security on all PII.

entities

Tracked public bodies

  • · id (uuid)
  • · name
  • · type
  • · state
  • · zip
findings

Civic records & content

  • · id (uuid)
  • · entity_id
  • · title
  • · severity
  • · status
action_log

User engagement events

  • · id (uuid)
  • · user_id
  • · finding_id
  • · level
  • · points
user_profiles

Participant profiles

  • · id (uuid)
  • · state
  • · zip
  • · interests
  • · user_type
oversight_refs

Jurisdiction mapping

  • · id (uuid)
  • · state
  • · zip
  • · entity_id
org_accounts

Organization tenants

  • · id (uuid)
  • · name
  • · tier
  • · seats

Participants vs Observers

Participants

Users who take a logged action (any level 1–6). Counted in findings.participants.

Observers

Users who view but don't act. Counted in findings.observers. Never merged with participants.

Security

Row-level security across all tables

Every user row in user_profiles and action_log is scoped to its owner. Admins query through service-role policies; participants only see their own activity.