01 — E-PID Arhitektuuriprintsiibid

Eesti Põllumajanduse Integreeritud Digitaalökosüsteem

Viis põhiprintsiipi, mis juhivad kogu süsteemiarhitektuuri ja arendusotsuseid.

💾

Andmesuveräänsus

Local-first, 0 latentsust, kasutaja kontrollib andmeid

🧩

Modulaarsus

Microservices arhitektuur, sõltumatud teenused

🔗

Koostalitlusvõime

X-tee, ISOBUS ISO 11783, OGC standardid

🛡️

Security by Design

Krüpteerimine, RBAC, auditlogi, gVisor

📈

Skaleeritavus

Serverless Cloud Run, 0→∞ skaleerimine

02 — Süsteemiarhitektuur

Kihiline arhitektuur

Client
Flutter UI (Skia/Impeller)Drift SQLiteSpatiaLiteHive NoSQLWhisper ASRMapLibreRiverpod
Gateway
API GatewayCloud RunX-tee AdapterJWT AuthRate LimitergVisor
Services
Sync EngineGIS ProcessingTelematicsAI/ML EnginesRAG PipelineReportsNotifications
Data
Cloud SQLPostgreSQL+PostGISpgvectorGIST IndexCloud StorageEPSG:3301
External
PRIA X-teePRIA WFSPHT APIMaa-ametIlmateenistusEarth EngineMerit AktivaDirecto
03 — Flutter mobiilrakendus

Kliendikihi arhitektuur

📖

Data Read Path

Kõik lugemisoperatsioonid toimuvad lokaalselt Drift/SQLite kaudu — lugemisaeg ~16ms. Riverpod StreamProvider jälgib automaatselt andmebaasi muudatusi ja uuendab UI-d reaalajas.

UI Widget → Riverpod Provider → Drift DAO → SQLite Query (~16ms) → Stream<List<T>>
✏️

Data Write Path

Kirjutamisoperatsioonid salvestavad kohe lokaalselt ja lisavad sync-järjekorda. Sync Manager taustal proovib saata pilve — ebaõnnestumise korral retry koos exponential backoff-iga.

User Action → Drift INSERT (local) → Sync Queue → Sync Manager (background) → Cloud API → Conflict Resolution → ACK
Drift/SpatiaLite andmebaasiskeem (täielik)
-- Põllumassiivid (PRIA WFS-st imporditud) CREATE TABLE field_parcels ( id TEXT PRIMARY KEY, pria_id TEXT UNIQUE, geometry BLOB NOT NULL, -- SpatiaLite POLYGON centroid BLOB, -- SpatiaLite POINT area_ha REAL NOT NULL, crop_type TEXT, crop_variety TEXT, soil_type TEXT, cadastre_nr TEXT, owner_id TEXT NOT NULL, sync_status TEXT DEFAULT 'pending', updated_at INTEGER NOT NULL, version INTEGER DEFAULT 1, CONSTRAINT valid_area CHECK (area_ha > 0) ); CREATE INDEX idx_parcels_owner ON field_parcels(owner_id); CREATE INDEX idx_parcels_sync ON field_parcels(sync_status); -- Põllutööde logi (häälsisestusest) CREATE TABLE field_operations ( id TEXT PRIMARY KEY, parcel_id TEXT REFERENCES field_parcels(id), operation_type TEXT NOT NULL, -- spray|fertilize|harvest|sow|till operation_date INTEGER NOT NULL, product_name TEXT, product_amount REAL, product_unit TEXT, -- kg|l|t area_treated_ha REAL, voice_transcript TEXT, whisper_confidence REAL, ner_structured TEXT, -- JSON from EstBERT weather_temp_c REAL, weather_wind_ms REAL, weather_humidity REAL, operator_id TEXT, offline_created INTEGER DEFAULT 1, sync_status TEXT DEFAULT 'pending', synced_at INTEGER, version INTEGER DEFAULT 1 ); CREATE INDEX idx_ops_parcel ON field_operations(parcel_id); CREATE INDEX idx_ops_date ON field_operations(operation_date); CREATE INDEX idx_ops_sync ON field_operations(sync_status); -- Offline kaardiklotsid CREATE TABLE offline_map_tiles ( z INTEGER, x INTEGER, y INTEGER, tile_data BLOB NOT NULL, source TEXT DEFAULT 'maaamet', expires_at INTEGER, PRIMARY KEY (z, x, y, source) ); -- Laohaldus CREATE TABLE inventory ( id TEXT PRIMARY KEY, product_name TEXT NOT NULL, category TEXT, -- fertilizer|pesticide|seed|fuel quantity REAL NOT NULL, unit TEXT NOT NULL, batch_nr TEXT, expiry_date INTEGER, price_eur REAL, updated_at INTEGER, sync_status TEXT DEFAULT 'pending' ); -- Sync järjekord CREATE TABLE sync_queue ( id INTEGER PRIMARY KEY AUTOINCREMENT, table_name TEXT NOT NULL, record_id TEXT NOT NULL, operation TEXT NOT NULL, -- INSERT|UPDATE|DELETE payload TEXT NOT NULL, -- JSON created_at INTEGER NOT NULL, retry_count INTEGER DEFAULT 0, last_error TEXT );
04 — Offline-First strateegia

Konflikti lahendamine

Neli strateegiat andmekonfliktide lahendamiseks offline→online sünkroonimisel.

Last-Write-Wins (LWW)
Ajatemplipõhine — uusim kirje võidab. Lihtne, kiire, ideaalne metaandmetele.
Semantic Merge
Valdkonnaspetsiifiline — erinevad väljad ühendatakse automaatselt.
Manual Resolution
Kasutajale kuvatakse mõlemad versioonid — valib ise. Kriitiliste andmete jaoks.
Delta-Based
Ainult muudatused saadetakse — vähendab andmemahtu ja konflikte.
Konflikti strateegia andmetüübi kaupa
AndmetüüpStrateegiaPõhjus
field_parcels.geometryManualGeomeetria muutus on kriitiline
field_parcels.crop_typeLWWÜks väärtus, harva muutub
field_operations.*Semantic MergeErinevad väljad ühendatakse
inventory.quantityDelta-BasedMuudatus on +/- delta
sync_queueAppend-only logi
05 — GCP pilveinfrastruktuur

GCP infrastruktuur

☁️

Cloud Run

Serverless konteinerid, 0→∞ skaleerimine, gVisor sandbox, automaatne TLS. API Gateway ja Sync teenused.

🔧

GKE (Kubernetes)

Raskete AI/ML tööde jaoks: Whisper treenimise pipeline, RAG indekseerimine, GIS batch-töötlus. A100/T4 GPU node pool.

🗄️

PostGIS + EPSG:3301

Cloud SQL PostgreSQL + PostGIS. L-EST97 (EPSG:3301). GIST ruumiindeksid, CLUSTER optimeeritud.

🏗️

Terraform IaC

Täielik infrastruktuur koodina. GCS state locking. DEV/STAGE/PROD keskkonnad.

Terraform kataloogistruktuur
terraform/ ├── environments/ │ ├── dev/ │ │ ├── main.tf │ │ ├── variables.tf │ │ └── terraform.tfvars │ ├── staging/ │ └── prod/ ├── modules/ │ ├── cloud-run/ │ ├── cloud-sql/ │ ├── gke-cluster/ │ ├── networking/ │ ├── iam/ │ └── monitoring/ ├── backend.tf # GCS state locking └── versions.tf
PostGIS pilveandmebaasi skeem
-- Põllumassiivid pilveandmebaasis (PostGIS) CREATE TABLE IF NOT EXISTS field_parcels ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), pria_id TEXT UNIQUE, owner_id UUID NOT NULL REFERENCES users(id), geometry geometry(POLYGON, 3301) NOT NULL, centroid geometry(POINT, 3301) GENERATED ALWAYS AS (ST_Centroid(geometry)) STORED, area_ha NUMERIC(10,4) NOT NULL GENERATED ALWAYS AS ( ST_Area(geometry) / 10000.0 ) STORED, crop_type TEXT, soil_type TEXT, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now(), version INTEGER DEFAULT 1 ); -- GIST ruumiindeks + CLUSTER CREATE INDEX idx_parcels_geom ON field_parcels USING GIST (geometry); CLUSTER field_parcels USING idx_parcels_geom; -- Ruumipäring näide: kõik massiivid 5km raadiuses SELECT id, pria_id, crop_type, ST_Area(geometry)/10000 AS area_ha FROM field_parcels WHERE ST_DWithin( geometry, ST_Transform( ST_SetSRID(ST_MakePoint(26.0, 58.5), 4326), 3301 ), 5000 -- 5km raadiuses );
06 — X-tee & PRIA integratsioon

Riikliku infrastruktuuri sild

📱
Flutter App
🔌
REST/JSON
🔄
X-tee Adapter
📜
SOAP/XML
🏛️
PRIA e-teenus
X-tee adapter on meie REST→SOAP teisenduskiht. Flutter rakendus saadab puhta JSON-i, adapter konverteerib PRIA SOAP/XML formaati ja lisab vajalikud X-Road päised (X-Road-UserId, sertifikaadid). See tähendab, et mobiilirakendus ei pea kunagi tegelema XML-iga — kogu keerukus on isoleeritud adapter-teenuses.
X-tee adapter koodinäide
// X-tee adapter: REST/JSON → SOAP/XML class XteeAdapter { final String securityServerUrl; final X509Certificate clientCert; Future<PriaResponse> submitFieldJournal( FieldJournalEntry entry ) async { final soapEnvelope = buildSoapEnvelope( service: 'pria-pht', method: 'submitFieldOperation', headers: { 'X-Road-UserId': entry.farmerId, 'X-Road-Id': generateMessageId(), 'X-Road-Service': 'EE/GOV/70000734/pria-pht/v1', }, body: fieldEntryToXml(entry), ); final response = await httpClient.post( Uri.parse(securityServerUrl), headers: { 'Content-Type': 'text/xml; charset=utf-8', 'SOAPAction': 'submitFieldOperation', }, body: soapEnvelope, ); return PriaResponse.fromSoapXml(response.body); } }
PRIA WFS päring (põllumassiivid)
// PRIA WFS — põllumassiivide import GET https://kaardirakendus.pria.ee/geoserver/wfs ?service=WFS &version=2.0.0 &request=GetFeature &typeName=pria:field_parcels &srsName=EPSG:3301 &outputFormat=application/json &CQL_FILTER=owner_reg_code='12345678' // Vastus: GeoJSON FeatureCollection { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[[6520000,648000], ...]] }, "properties": { "pria_id": "PM-2024-001234", "area_ha": 12.45, "land_use": "P" // P=põld, R=rohumaa } }] }
07 — AI/ML süsteemid

Tehisintellekt ja masinõpe

🎙️

Whisper peenhäälestamise pipeline

📚
Corpus
🔧
LoRA Train
📦
INT8 Quant
ONNX Export
📱
Flutter FFI

Treeningkorpus: Mozilla Common Voice (et) + Kuku raadio "Maatund" saated. HuggingFace Transformers Seq2SeqTrainer. GPU: NVIDIA A100 (treenimine) / T4 (inferents).

Whisper LoRA treenimise konfiguratsioon
{ "model_name": "openai/whisper-small", "language": "et", "task": "transcribe", "lora_config": { "r": 16, "lora_alpha": 32, "lora_dropout": 0.05, "target_modules": [ "q_proj", "v_proj", "k_proj", "out_proj" ] }, "training_args": { "learning_rate": 1e-5, "warmup_steps": 500, "max_steps": 5000, "per_device_train_batch_size": 16, "gradient_accumulation_steps": 2, "fp16": true, "evaluation_strategy": "steps", "eval_steps": 500, "save_steps": 1000, "logging_steps": 50 }, "quantization": { "type": "INT8", "calibration_samples": 1000, "export_format": "ONNX" } }
🧠

EstBERT NER post-processing

Pärast Whisper transkriptsiooni töötleb EstBERT-põhine NER mudel teksti ja eraldab struktureeritud andmed.

// Häälsisestus → Struktureeritud andmed Sisend: "külvasin kakssada kilo otra põllule kolm" ↓ Whisper ASR Transcript: "külvasin kakssada kilo otra põllule kolm" ↓ EstBERT NER { "operation": "sow", "product": "oder", "amount": 200, "unit": "kg", "field_ref": "põld #3", "confidence": 0.94 }
🤖

RAG arhitektuur (pilvepõhine)

Retrieval-Augmented Generation kasutajapäringuile. pgvector embeddings, Router Agent valib tee, GPT-4o / Claude 3.5 Sonnet vastab.

Päring
🔀
Router Agent
🔍
pgvector
🛠️
Tool Agent
💬
Vastus
08 — Integratsioonid ja jätkusuutlikkus

Välised süsteemid ja rohepööre

Integratsioonide kaart
SüsteemProtokollAndmedStaatus
PRIA e-PRIAX-tee SOAPPõlluraamat, toetusedMVP
PRIA WFSOGC WFS 2.0Põllumassiivid, piiridMVP
Maa-amet WMSOGC WMSOrtofotod, katasterMVP
IlmateenistusREST JSONIlmaprognoos, ajaluguMVP
Merit AktivaREST APIArved, kulud2027
DirectoXMLRaamatupidamine2027
ISOBUS ISO 11783CAN-busMasinate telemaatika2028
AEMP 2.0REST JSONOEM telemaatika2028
Sentinel-2Earth EngineNDVI vegetatsiooniindeks2029
Cool Farm ToolAPISüsiniku jalajälg2029
IPCC 2019FaktoridCO2e arvutused2029
🌿

Jätkusuutlikkusmoodulid (2029+)

Cool Farm Tool süsiniku jalajälje arvutus. IPCC 2019 emissioonifaktorid. Sentinel-2 NDVI vegetatsiooniindeks. Euroopa süsinikukrediitide turg.

Cool Farm ToolIPCC 2019Sentinel-2 EU ETS
🚜

Masinate telemaatika (2028+)

ISOBUS ISO 11783 standardne masinaliides. AEMP 2.0 OEM telemaatika. Automaatne tööaja ja kütusekulu jälgimine.

ISOBUSAEMP 2.0 CAN-bus
Kontakt

Küsimusi arhitektuuri kohta?

Võta ühendust, et arutada tehnilist arhitektuuri ja koostöövõimalusi.