chore: initial commit — UdyamLinc backend, phases A-E

Spring Boot 4 / Java 17 / Postgres. Masters and serving (A), Agmarknet and
climate ingestion (B), feature store with 14 derivations (C), SpEL rule
engine and risk scoring (D).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
LincPay
2026-08-06 13:30:14 +05:30
co-authored by Claude Opus 5
commit 1b9b02f2c7
100 changed files with 7935 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
spring.application.name=udyamlinc-backend
server.port=8082
server.servlet.context-path=/api/v1/udyam
# JPA & Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.default_schema=public
spring.jpa.open-in-view=false
# DataSource — UdyamLinc_DEMO
spring.datasource.url=${UDYAM_DB_URL:jdbc:postgresql://localhost:5432/UdyamLinc_DEMO}
spring.datasource.username=${UDYAM_DB_USERNAME:postgres}
spring.datasource.password=${UDYAM_DB_PASSWORD:root}
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
# HikariCP
spring.datasource.hikari.connection-timeout=10000
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.auto-commit=true
# throw NoHandlerFoundException for 404s
spring.mvc.throw-exception-if-no-handler-found=true
jwt.secret=55647961_6D4C_696E_6320_4E41_4241_5244_5F32_3032_365F_4C69_6E63_4675_7369_6F6E_5F48_6163_6B61_74686F6E
# 24 hours
jwt.expiration=86400000
# The Vite dev server for UdyamLinc-UI (5180 is BharatLinc)
udyam.cors.allowed-origins=http://localhost:5182,http://127.0.0.1:5182,http://localhost:4173
# Forecast horizon in months — the deck's 3–6 month early-warning window
udyam.forecast.horizon-months=6
# Composite Stress Score band thresholds; map these to the institution's watchlist
udyam.risk.red-threshold=65
udyam.risk.watch-threshold=35
# ── Risk & rule engine (ARCHITECTURE Phase D) ───────────────
# Which ScoringStrategy binds. RULE today; MODEL when the LightGBM heads land —
# that swap is this line, not a rewrite.
udyam.risk.engine=RULE
udyam.risk.model-version=rule-v1.0.0
# Where a family lands with no usable feature. Neutral, not innocent: scoring 0
# would read as "safe on this dimension" when the truth is that we do not know.
udyam.risk.family-prior=40
# A rule engine reports low confidence by design.
udyam.risk.rule-confidence-ceiling=70
# Nightly scoring, an hour behind ingestion so it scores what that job wrote.
udyam.risk.scheduled=${UDYAM_SCORING_ENABLED:false}
udyam.risk.cron=0 0 3 * * *
# Seed the demo portfolio (142 enterprises) on first boot
udyam.seed.enabled=true
# ── Ingestion (ARCHITECTURE Phase B) ────────────────────────
# Off by default: a demo boot must never call a government endpoint. Turn on for
# the pilot, or trigger a one-off pass with POST /admin/ingestion/run.
udyam.ingestion.enabled=${UDYAM_INGESTION_ENABLED:false}
udyam.ingestion.cron=0 0 2 * * *
udyam.ingestion.zone=Asia/Kolkata
udyam.ingestion.http.connect-timeout-ms=10000
udyam.ingestion.http.read-timeout-ms=30000
# Agmarknet mandi prices — data.gov.in Open Government Data API.
# Register at https://data.gov.in for a key; without one the run records SKIPPED.
udyam.ingestion.datagov.api-key=${DATAGOV_API_KEY:}
udyam.ingestion.datagov.base-url=https://api.data.gov.in/resource
# "Variety-wise Daily Market Prices Data of Commodity" (Agmarknet)
udyam.ingestion.datagov.resource-id=${DATAGOV_RESOURCE_ID:9ef84268-d588-465a-a308-a864a43d0070}
udyam.ingestion.datagov.page-limit=1000
# Filter names must match the resource's own field names; they differ by resource version.
udyam.ingestion.datagov.field.state=state
udyam.ingestion.datagov.field.district=district
udyam.ingestion.datagov.field.commodity=commodity
udyam.ingestion.mandi.lookback-weeks=12
# Climate — Open-Meteo reanalysis archive. No key. The archive trails real time,
# hence the lag; the baseline is fetched once per district and cached as normals.
udyam.ingestion.climate.base-url=https://archive-api.open-meteo.com/v1/archive
udyam.ingestion.climate.timezone=Asia/Kolkata
udyam.ingestion.climate.lookback-weeks=12
udyam.ingestion.climate.lag-days=5
udyam.ingestion.climate.heat-threshold-c=40
udyam.ingestion.climate.baseline-from=1995-01-01
udyam.ingestion.climate.baseline-to=2024-12-31
# ── Feature store (ARCHITECTURE Phase C) ────────────────────
# Window sizes for the derivations. A level is not a feature; every one of these
# turns a level into a change, a ratio or an anomaly against one of these windows.
udyam.features.price-window-weeks=8
udyam.features.recent-window-weeks=4
udyam.features.climate-window-weeks=8
# Below this many same-season observations a z-score is noise, so it stays null.
udyam.features.min-zscore-samples=6
logging.level.com.lincfusion.udyamlinc=INFO