feat(boc): Complete Business Operations Center v1.0

- Go backend API with full CRUD for all modules (CRM, Sales, Finance, HR, Legal, Marketing, Support, Purchase, Inventory, Projects, Automation, Analytics)
- Rust analytics service with parallel report generation
- C runtime with POSIX shared memory IPC
- PostgreSQL schema with 30+ tables, full migrations
- Redis cache, sessions, pub/sub
- Kafka event streaming with Zookeeper
- WebSocket hub for real-time updates
- Automation engine with cron jobs, workflows, event triggers
- JWT authentication, multi-tenant from start
- Docker Compose with all services
- Nginx reverse proxy with rate limiting
- Integration tests passing
- Feature gap analysis against Fortnox/Odoo/Visma

Refs: BOC-001
This commit is contained in:
Bernt
2026-07-12 12:41:35 +00:00
parent 4789a7fb48
commit 58ca4e68db
26666 changed files with 575891 additions and 2074516 deletions
+180
View File
@@ -0,0 +1,180 @@
-- ATM Anomaly Detection Database Schema
-- PostgreSQL / SQLite compatible
-- Main ATM locations table
CREATE TABLE atm_locations (
id SERIAL PRIMARY KEY,
atm_id VARCHAR(50) UNIQUE NOT NULL,
bank_name VARCHAR(100),
branch_name VARCHAR(100),
address TEXT,
latitude DECIMAL(10, 8),
longitude DECIMAL(11, 8),
city VARCHAR(100),
country VARCHAR(100),
installation_date DATE,
atm_model VARCHAR(100),
camera_count INTEGER DEFAULT 1,
status VARCHAR(20) DEFAULT 'active', -- active, inactive, maintenance, removed
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Image captures from ATMs
CREATE TABLE atm_captures (
id SERIAL PRIMARY KEY,
atm_id VARCHAR(50) NOT NULL REFERENCES atm_locations(atm_id),
capture_timestamp TIMESTAMP NOT NULL,
camera_angle VARCHAR(20), -- front, side, top, wide
image_path VARCHAR(500) NOT NULL,
image_hash VARCHAR(64), -- SHA-256 for deduplication
file_size_bytes INTEGER,
width_pixels INTEGER,
height_pixels INTEGER,
lighting_condition VARCHAR(20), -- day, night, indoor, outdoor
weather_condition VARCHAR(50), -- clear, rain, snow, fog
blur_score DECIMAL(5, 4), -- 0.0 to 1.0, higher is sharper
quality_score DECIMAL(5, 4), -- overall image quality
metadata JSONB, -- flexible metadata storage
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Anomaly categories/types
CREATE TABLE anomaly_types (
id SERIAL PRIMARY KEY,
type_code VARCHAR(50) UNIQUE NOT NULL,
type_name VARCHAR(100) NOT NULL,
description TEXT,
severity_level INTEGER CHECK (severity_level BETWEEN 1 AND 5),
category VARCHAR(50), -- physical, environmental, functional, security
requires_immediate_action BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Detected anomalies
CREATE TABLE detected_anomalies (
id SERIAL PRIMARY KEY,
capture_id INTEGER NOT NULL REFERENCES atm_captures(id),
anomaly_type_id INTEGER NOT NULL REFERENCES anomaly_types(id),
confidence_score DECIMAL(5, 4) NOT NULL, -- 0.0 to 1.0
bounding_box JSONB, -- {x, y, width, height} in normalized coordinates
severity_score DECIMAL(5, 4), -- calculated severity
model_version VARCHAR(50), -- which model detected this
detection_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
verified_by_human BOOLEAN DEFAULT FALSE,
human_verdict VARCHAR(20), -- confirmed, false_positive, uncertain
human_notes TEXT,
status VARCHAR(20) DEFAULT 'open', -- open, acknowledged, resolved, false_positive
resolved_at TIMESTAMP,
resolution_notes TEXT,
assigned_to VARCHAR(100), -- technician or team
priority INTEGER CHECK (priority BETWEEN 1 AND 5),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Baseline/reference images for comparison
CREATE TABLE baseline_images (
id SERIAL PRIMARY KEY,
atm_id VARCHAR(50) NOT NULL REFERENCES atm_locations(atm_id),
camera_angle VARCHAR(20),
baseline_type VARCHAR(20) DEFAULT 'normal', -- normal, maintenance, installation
image_path VARCHAR(500) NOT NULL,
established_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP, -- when baseline should be refreshed
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Change detection history
CREATE TABLE change_detections (
id SERIAL PRIMARY KEY,
atm_id VARCHAR(50) NOT NULL REFERENCES atm_locations(atm_id),
camera_angle VARCHAR(20),
reference_capture_id INTEGER REFERENCES atm_captures(id),
current_capture_id INTEGER NOT NULL REFERENCES atm_captures(id),
change_score DECIMAL(5, 4), -- overall change magnitude
structural_similarity DECIMAL(5, 4), -- SSIM score
pixel_difference DECIMAL(5, 4), -- percentage of changed pixels
significant_change BOOLEAN DEFAULT FALSE,
detected_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
reviewed_by INTEGER,
review_notes TEXT
);
-- Model training runs
CREATE TABLE model_training_runs (
id SERIAL PRIMARY KEY,
model_name VARCHAR(100) NOT NULL,
model_version VARCHAR(50) NOT NULL,
training_start TIMESTAMP,
training_end TIMESTAMP,
dataset_size INTEGER,
epochs INTEGER,
batch_size INTEGER,
learning_rate DECIMAL(10, 8),
final_loss DECIMAL(10, 6),
validation_map DECIMAL(5, 4), -- mean average precision
validation_accuracy DECIMAL(5, 4),
model_path VARCHAR(500),
config JSONB,
status VARCHAR(20) DEFAULT 'running', -- running, completed, failed
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Alerting and notifications
CREATE TABLE alerts (
id SERIAL PRIMARY KEY,
anomaly_id INTEGER REFERENCES detected_anomalies(id),
alert_type VARCHAR(50), -- email, sms, webhook, dashboard
recipient VARCHAR(200),
sent_at TIMESTAMP,
delivered_at TIMESTAMP,
read_at TIMESTAMP,
status VARCHAR(20) DEFAULT 'pending', -- pending, sent, delivered, failed
retry_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Maintenance logs
CREATE TABLE maintenance_logs (
id SERIAL PRIMARY KEY,
atm_id VARCHAR(50) NOT NULL REFERENCES atm_locations(atm_id),
maintenance_type VARCHAR(50), -- repair, cleaning, inspection, upgrade
technician_name VARCHAR(100),
started_at TIMESTAMP,
completed_at TIMESTAMP,
description TEXT,
parts_replaced JSONB,
cost DECIMAL(10, 2),
before_images JSONB,
after_images JSONB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Indexes for performance
CREATE INDEX idx_captures_atm_id ON atm_captures(atm_id);
CREATE INDEX idx_captures_timestamp ON atm_captures(capture_timestamp);
CREATE INDEX idx_anomalies_capture ON detected_anomalies(capture_id);
CREATE INDEX idx_anomalies_type ON detected_anomalies(anomaly_type_id);
CREATE INDEX idx_anomalies_status ON detected_anomalies(status);
CREATE INDEX idx_anomalies_created ON detected_anomalies(created_at);
CREATE INDEX idx_changes_atm ON change_detections(atm_id);
CREATE INDEX idx_alerts_anomaly ON alerts(anomaly_id);
-- Insert default anomaly types
INSERT INTO anomaly_types (type_code, type_name, description, severity_level, category, requires_immediate_action) VALUES
('physical_damage', 'Physical Damage', 'Visible damage to ATM structure, screen, or components', 4, 'physical', FALSE),
('vandalism', 'Vandalism', 'Intentional damage including scratches, dents, or broken parts', 4, 'physical', FALSE),
('graffiti', 'Graffiti', 'Unauthorized markings or paint on ATM surfaces', 2, 'environmental', FALSE),
('dirt_debris', 'Dirt and Debris', 'Excessive dirt, leaves, or debris blocking ATM or camera', 2, 'environmental', FALSE),
('obstruction', 'Obstruction', 'Objects blocking access to ATM or camera view', 3, 'environmental', FALSE),
('skimming_device', 'Skimming Device', 'Suspicious device attached to card reader or PIN pad', 5, 'security', TRUE),
('suspicious_attachment', 'Suspicious Attachment', 'Unknown device or object attached to ATM', 5, 'security', TRUE),
('out_of_service', 'Out of Service', 'ATM displaying out of service message or dark screen', 3, 'functional', FALSE),
('screen_damage', 'Screen Damage', 'Cracked, discolored, or non-functional display', 3, 'physical', FALSE),
('cash_jam', 'Cash Jam', 'Cash dispenser showing signs of jam or malfunction', 3, 'functional', FALSE),
('receipt_jam', 'Receipt Jam', 'Receipt printer showing signs of jam or empty', 2, 'functional', FALSE),
('lighting_failure', 'Lighting Failure', 'ATM area poorly lit or lights not functioning', 3, 'environmental', FALSE),
('camera_blind', 'Camera Blind', 'Security camera blocked, damaged, or misaligned', 4, 'security', FALSE),
('network_down', 'Network Down', 'ATM showing network connectivity issues', 3, 'functional', FALSE);