Codename: SentinelCredits
A multimodal AI intake and triage system for public safety incidents, powered by Gemini, Opus, Qdrant, and Solana.
APSIC is an AI-powered pipeline that processes public safety incidents across text, images, audio, and video. It intelligently classifies, triages, and routes cases while maintaining a complete audit trail.
Pipeline: Intake โ Understand โ Decide โ Review โ Deliver
- ๐ค Multimodal AI Processing - Gemini analyzes text, images, audio, and video
- ๐ Opus Workflow Orchestration - Structured pipeline with human-in-the-loop
- ๐ Vector Search - Qdrant finds similar historical incidents
- ๐ Blockchain Credits - Solana SPL token for access gating
- ๐ Complete Audit Trail - Full provenance and transparency
- โก Real-time Triage - Automatic severity classification and routing
- Product Requirements Document (PRD) - Complete product specification
- Technical Architecture - System design and data flow
- API Specification - REST API reference
- Implementation Roadmap - Hackathon milestones and tasks
โโโโโโโโโโโโโโโ
โ Frontend โ (Next.js + Tailwind)
โ Reporter โ โ Submit incident (text + media)
โโโโโโโโฌโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโ
โ Backend โ (Node.js + TypeScript)
โ API โ โ Check credits, trigger workflow
โโโโโโโโฌโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ Opus โ โโโโโโ โ Gemini โ โ Qdrant โ
โ Workflow โ โ(Multimodal) โ โ (Vector) โ
โโโโโโโโฌโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโฌโโโโโโโ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ PostgreSQL โ
โ + S3 Storage โ
โโโโโโโโโโโโโโโโโโโ
- Node.js 20+
- PostgreSQL 15+
- Docker (optional, for local services)
- Solana CLI (optional, for token testing)
- Clone the repository
git clone https://github.com/yourusername/apsic.git
cd apsic- Install dependencies
# Backend
cd services/backend
npm install
# Frontend
cd ../../apps/web-frontend
npm install- Set up environment variables
Create .env files:
services/backend/.env:
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/apsic
# API Keys
OPUS_API_KEY=your_opus_api_key
GEMINI_API_KEY=your_gemini_api_key
# Solana
SOLANA_RPC_URL=https://api.devnet.solana.com
SIC_TOKEN_MINT=your_spl_token_mint_address
# Qdrant
QDRANT_URL=http://localhost:6333
QDRANT_API_KEY= # Optional for cloud
# Storage
AWS_ACCESS_KEY_ID=your_aws_key
AWS_SECRET_ACCESS_KEY=your_aws_secret
AWS_S3_BUCKET=apsic-uploads
AWS_REGION=us-east-1
# Server
PORT=4000
NODE_ENV=developmentapps/web-frontend/.env.local:
NEXT_PUBLIC_API_URL=http://localhost:4000
NEXT_PUBLIC_SOLANA_NETWORK=devnet- Start local services (Docker Compose)
docker-compose up -dThis starts:
- PostgreSQL (port 5432)
- Qdrant (port 6333)
- Run database migrations
cd services/backend
npx prisma migrate dev
npx prisma generate- Seed demo data (optional)
npm run seed- Start the development servers
# Terminal 1: Backend
cd services/backend
npm run dev # Runs on http://localhost:4000
# Terminal 2: Frontend
cd apps/web-frontend
npm run dev # Runs on http://localhost:3000- Open the app
Navigate to http://localhost:3000
-
Connect Wallet
- Click "Connect Wallet" and select your Solana wallet (Phantom, Solflare, etc.)
- For demo purposes, you can use the "Mock Wallet" option
-
Fill the Form
- Enter incident description (text)
- Optionally select incident type (or use "Auto-detect")
- Upload image/audio/video files (optional)
-
Submit
- Click "Submit Incident"
- System checks your credit balance (requires โฅ1 credit)
- Incident is sent to Opus for processing
-
View Results
- After ~30 seconds, results appear:
- Severity score and label
- AI-generated summary
- Recommended actions
- Similar past incidents
- Download audit log (JSON)
- After ~30 seconds, results appear:
Navigate to http://localhost:3000/incidents to view all incidents.
Features:
- Filter by severity, type, status
- Sort by date, severity
- Click incident to view details
- Download audit logs
# Backend tests
cd services/backend
npm test
# Frontend tests
cd apps/web-frontend
npm testScenario 1: High-Severity Harassment Report
- Text: "Student is receiving threatening messages with violent language. Attached screenshots show escalating threats."
- Image: Upload screenshot of threatening messages
- Expected: Severity = High, Route = Escalate
Scenario 2: Low-Severity Noise Complaint
- Text: "Loud music from neighboring dorm room at 10pm."
- Expected: Severity = Low, Route = LogOnly
Scenario 3: Critical Accident
- Text: "Student fell down stairs in Building 4. Unconscious and bleeding."
- Expected: Severity = Critical, Route = Immediate
Scenario 4: Insufficient Credits
- Set wallet credits to 0
- Try to submit incident
- Expected: Error "Insufficient credits"
apsic/
โโโ apps/
โ โโโ web-frontend/ # Next.js frontend
โ โโโ src/
โ โ โโโ app/ # App Router pages
โ โ โโโ components/ # React components
โ โ โโโ lib/ # Utilities
โ โ โโโ store/ # State management
โ โโโ package.json
โ
โโโ services/
โ โโโ backend/ # Node.js API server
โ โ โโโ src/
โ โ โ โโโ routes/ # API routes
โ โ โ โโโ services/ # Business logic
โ โ โ โโโ lib/ # Client libraries
โ โ โ โโโ middleware/ # Express middleware
โ โ โโโ package.json
โ โ
โ โโโ scripts/ # Utility scripts
โ โโโ seedDemoData.ts # Seed database
โ
โโโ docs/ # Documentation
โ โโโ PRD.md
โ โโโ ARCHITECTURE.md
โ โโโ API_SPEC.md
โ โโโ ROADMAP.md
โ
โโโ docker-compose.yml # Local services
โโโ README.md
โโโ package.json
- Update TypeScript Types
// services/backend/src/types/index.ts
export type IncidentType =
| 'harassment'
| 'accident'
| 'cyber'
| 'infrastructure'
| 'your_new_type' // Add here
| 'other';- Update Gemini Prompts
// services/backend/src/lib/geminiClient.ts
const INCIDENT_TYPES = [
'harassment',
'accident',
'cyber',
'infrastructure',
'your_new_type', // Add here
'other'
];- Update Frontend Selector
// apps/web-frontend/src/components/reporter/IncidentForm.tsx
const INCIDENT_TYPES = [
{ value: 'auto', label: 'Auto-detect' },
// ...
{ value: 'your_new_type', label: 'Your New Type' },
];Edit the workflow definition in the Opus dashboard or via API:
- Navigate to Opus Workflows
- Select
APSIC_Public_Safety_Intake_v1 - Modify nodes (e.g., add new rules in "Decide" stage)
- Save and test
To switch from Gemini embeddings to OpenAI or custom model:
- Update
services/backend/src/lib/embeddingService.ts - Change
generateEmbedding()implementation - Update Qdrant collection dimension if needed
- Re-index existing incidents
Frontend (Vercel):
cd apps/web-frontend
vercel --prodBackend (Railway / AWS):
cd services/backend
railway up
# OR
docker build -t apsic-backend .
docker push your-registry/apsic-backendDatabase (AWS RDS / Supabase):
- Create PostgreSQL instance
- Update
DATABASE_URLin environment variables - Run migrations:
npx prisma migrate deploy
Qdrant (Cloud or Self-Hosted):
- Sign up at Qdrant Cloud
- Create cluster
- Update
QDRANT_URLandQDRANT_API_KEY
Ensure all secrets are set in your deployment platform:
OPUS_API_KEYGEMINI_API_KEYDATABASE_URLQDRANT_URLQDRANT_API_KEYSOLANA_RPC_URL(use Mainnet or premium RPC)AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_S3_BUCKET
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- TypeScript for all code
- ESLint + Prettier for linting and formatting
- Conventional Commits for commit messages
This project is licensed under the MIT License. See LICENSE for details.
- Gemini - Multimodal AI processing
- Opus - Workflow orchestration
- Qdrant - Vector similarity search
- Solana - Blockchain infrastructure
- Next.js - Frontend framework
- Documentation: docs/
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Video Walkthrough: YouTube Link
Live Demo: https://apsic-demo.vercel.app
Built with โค๏ธ for safer communities