Second checkpoint

This commit is contained in:
2026-06-25 01:17:42 +05:00
parent 854ef138d0
commit 9cf791b789
90 changed files with 5504 additions and 988 deletions

View File

@@ -0,0 +1,6 @@
-- +goose Up
-- Enable PostGIS so datasets can carry a spatial geometry column.
CREATE EXTENSION IF NOT EXISTS postgis;
-- +goose Down
DROP EXTENSION IF EXISTS postgis;

View File

@@ -0,0 +1,14 @@
-- +goose Up
CREATE TABLE categories (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
parent_id UUID REFERENCES categories (id) ON DELETE RESTRICT,
name VARCHAR(255) NOT NULL,
description TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_categories_parent_id ON categories (parent_id);
-- +goose Down
DROP TABLE categories;

View File

@@ -0,0 +1,39 @@
-- +goose Up
CREATE TYPE file_type AS ENUM ('vector_with_kato', 'vector', 'raster');
CREATE TABLE datasets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
category_id UUID NOT NULL REFERENCES categories (id) ON DELETE RESTRICT,
code VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
unit VARCHAR(255),
filename VARCHAR(255) NOT NULL,
storage_key TEXT NOT NULL,
cog_storage_key TEXT, -- Cloud-Optimized GeoTIFF (raster only)
file_type file_type NOT NULL,
size_bytes BIGINT NOT NULL DEFAULT 0,
content_type VARCHAR(255) NOT NULL DEFAULT '',
properties JSONB,
meta JSONB,
automated BOOLEAN NOT NULL DEFAULT false,
status VARCHAR(255) NOT NULL DEFAULT 'pending',
-- vector_with_kato attribute-table parsing + mapping
attribute_columns JSONB, -- detected columns: [{name, samples}]
kato_column VARCHAR(255), -- user-selected KATO column
year_columns JSONB, -- mapping: [{column, date}]
parse_error TEXT, -- failure reason when status = 'failed'
-- Footprint/extent in EPSG:4326 (any geometry type). The SRID is constrained
-- so geometry and the derived bbox are always comparable.
geometry geometry(Geometry, 4326),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_datasets_category_id ON datasets (category_id);
CREATE INDEX idx_datasets_geometry ON datasets USING GIST (geometry);
CREATE INDEX idx_datasets_created_at ON datasets (created_at DESC);
-- +goose Down
DROP TABLE datasets;
DROP TYPE file_type;

View File

@@ -0,0 +1,12 @@
-- +goose Up
-- Sink for the generic example RabbitMQ consumer. Safe to drop once a real
-- async use case replaces the scaffold.
CREATE TABLE events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
kind VARCHAR(255) NOT NULL,
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- +goose Down
DROP TABLE events;

View File

@@ -0,0 +1,20 @@
-- +goose Up
-- Long-format (tidy) values unpivoted from a vector_with_kato dataset's
-- attribute table: one row per (KATO code, date). value holds numeric cells,
-- value_text holds non-numeric ones.
CREATE TABLE dataset_observations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
dataset_id UUID NOT NULL REFERENCES datasets (id) ON DELETE CASCADE,
kato_code TEXT NOT NULL,
date DATE NOT NULL,
value DOUBLE PRECISION,
value_text TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX uq_dataset_observations ON dataset_observations (dataset_id, kato_code, date);
CREATE INDEX idx_dataset_observations_dataset ON dataset_observations (dataset_id);
CREATE INDEX idx_dataset_observations_kato_date ON dataset_observations (kato_code, date);
-- +goose Down
DROP TABLE dataset_observations;

View File

@@ -1,11 +0,0 @@
-- +goose Up
CREATE TABLE datasets (
id UUID PRIMARY KEY default gen_random_uuid(),
name varchar(255),
description text,
created_at timestamp default now(),
updated_at timestamp default now()
);
-- +goose Down
DROP TABLE datasets;

View File

@@ -1,12 +0,0 @@
-- +goose Up
CREATE TABLE categories
(
id UUID PRIMARY KEY default gen_random_uuid(),
name varchar(255),
description text,
created_at timestamp default now(),
updated_at timestamp default now()
);
-- +goose Down
DROP TABLE categories;

View File

@@ -1,22 +0,0 @@
-- +goose Up
CREATE TYPE file_type AS ENUM ('vector_with_table', 'vector', 'raster');
CREATE TYPE file_validation_status AS ENUM ('pending', 'valid', 'failed');
CREATE TABLE files (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
filename VARCHAR(255) NOT NULL,
storage_key TEXT NOT NULL,
file_type file_type NOT NULL,
validation_status file_validation_status NOT NULL DEFAULT 'pending',
validation_error TEXT,
kato_column VARCHAR(255),
crs VARCHAR(64),
feature_count INTEGER,
uploaded_at TIMESTAMP NOT NULL DEFAULT now(),
updated_at TIMESTAMP NOT NULL DEFAULT now()
);
-- +goose Down
DROP TABLE files;
DROP TYPE file_validation_status;
DROP TYPE file_type;

10
migrations/embed.go Normal file
View File

@@ -0,0 +1,10 @@
// Package migrations embeds the SQL migration files so they can be applied from
// the single application binary (via the `gis migrate` subcommand).
package migrations
import "embed"
// FS holds the embedded goose migration files.
//
//go:embed *.sql
var FS embed.FS