58ca4e68db
- 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
181 lines
7.7 KiB
SQL
181 lines
7.7 KiB
SQL
-- 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);
|