Files
Claude VM a6c03a091e initial: split from gov-agreg — vreau.digital standalone platform
Moved from gov-agreg/src/pages/achizitii/* to root (drop prefix).
- 22 pages migrated, 127 files total
- All internal links: /achizitii/X → /X (176 occurrences fixed)
- AchizitiiLayout subnav rewritten: /X paths, top-right link to vreaudigital.ro hub
- BaseLayout new (vreau.digital branding, OG tags, site URL)
- astro.config.mjs: site https://vreau.digital, server output (was static)
- docker-compose: port 5096 (vreaudigital is 5095), container vreau-digital
- deploy.sh: paths /opt/vreau-digital, log /var/log/vreau-digital-deploy.log

Backend shared with gov-agreg:
- PostgreSQL satra (same schemas: seap, firms, anaf, anre, ...)
- Photon, Martin tiles
- Infisical /vreaudigital path (DATABASE_URL etc. shared)

build: PASS (npx astro check 0 errors, npm run build 5s vite + 10s server)
2026-05-13 00:10:32 +03:00

72 lines
2.8 KiB
PL/PgSQL

-- CPV nomenclature: 9,454 codes with Romanian names + EU emojis.
-- Loaded from samhallskod/cpv-eu (data sourced from official EU CPV 2008 XML).
BEGIN;
CREATE TABLE IF NOT EXISTS seap.cpv_codes (
code TEXT PRIMARY KEY, -- 8-digit (no check digit), e.g. '45000000'
code_full TEXT, -- 8-digit + check, e.g. '45000000-7'
name_ro TEXT NOT NULL,
name_en TEXT,
level INT NOT NULL, -- 1=division (45), 2=group (450), 3=class (4500), ...
division_code TEXT NOT NULL, -- first 2 digits + 6 zeroes, e.g. '45000000' (top-level parent)
parent_code TEXT, -- one level up
emoji TEXT, -- only set on division level
imported_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_cpv_division ON seap.cpv_codes(division_code);
CREATE INDEX IF NOT EXISTS idx_cpv_parent ON seap.cpv_codes(parent_code);
CREATE INDEX IF NOT EXISTS idx_cpv_level ON seap.cpv_codes(level);
CREATE INDEX IF NOT EXISTS idx_cpv_name_trgm ON seap.cpv_codes USING gin(name_ro gin_trgm_ops);
-- Helper: normalize "45123456-7" or "45123456" or empty → "45123456" (8-digit, no dash)
CREATE OR REPLACE FUNCTION seap.cpv_normalize(code TEXT)
RETURNS TEXT AS $$
BEGIN
IF code IS NULL OR code = '' THEN RETURN NULL; END IF;
-- Strip the check digit suffix (-X) and any whitespace
RETURN regexp_replace(trim(code), '-[0-9]$', '');
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
-- Helper: get division code (first 2 digits + 6 zeros)
CREATE OR REPLACE FUNCTION seap.cpv_division(code TEXT)
RETURNS TEXT AS $$
BEGIN
IF code IS NULL OR length(code) < 2 THEN RETURN NULL; END IF;
RETURN substr(seap.cpv_normalize(code), 1, 2) || '000000';
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
-- Get name_ro for a code, fallback to division name, fallback to code itself
CREATE OR REPLACE FUNCTION seap.cpv_name(code TEXT)
RETURNS TEXT AS $$
DECLARE
result TEXT;
BEGIN
SELECT name_ro INTO result FROM seap.cpv_codes WHERE code = seap.cpv_normalize($1);
IF result IS NOT NULL THEN RETURN result; END IF;
SELECT name_ro INTO result FROM seap.cpv_codes WHERE code = seap.cpv_division($1);
IF result IS NOT NULL THEN RETURN result; END IF;
RETURN $1;
END;
$$ LANGUAGE plpgsql STABLE;
-- Get top-level category name + emoji for any code
CREATE OR REPLACE VIEW seap.cpv_division_lookup AS
SELECT code AS division_code, name_ro AS division_name, emoji
FROM seap.cpv_codes WHERE level = 1;
-- Add denormalized columns to announcements for fast queries
ALTER TABLE seap.announcements ADD COLUMN IF NOT EXISTS cpv_division TEXT;
ALTER TABLE seap.announcements ADD COLUMN IF NOT EXISTS cpv_name_ro TEXT;
CREATE INDEX IF NOT EXISTS idx_ann_cpv_division ON seap.announcements(cpv_division);
COMMIT;