Files
udyamlinc-api/src/main/java/com/lincfusion/udyamlinc/features/FeatureDefinition.java
T
LincPayandClaude Opus 5 1b9b02f2c7 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>
2026-08-06 13:30:14 +05:30

71 lines
2.0 KiB
Java

package com.lincfusion.udyamlinc.features;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
/**
* The feature catalogue. A row here is the contract for one engineered
* indicator: what it means, what unit it carries, and how old it is allowed to
* be before anything downstream may act on it.
*
* <p>{@code stalenessToleranceDays} is the column trip-wires read. A rule firing
* on a three-week-old price is worse than no rule, and the tolerance is per
* feature because a mandi price goes stale in days while a CBS extract is
* monthly by design.
*/
@Entity
@Table(name = "feature_definition", indexes = @Index(name = "ix_feature_def_code", columnList = "code", unique = true))
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class FeatureDefinition {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/** snake_case, matching the name a trip-wire expression uses. */
@Column(nullable = false, unique = true, length = 48)
private String code;
@Column(nullable = false, length = 96)
private String label;
/** LIQUIDITY | BEHAVIOURAL | TREND_VOLATILITY | OBLIGATION_LOAD | EXTERNAL_SHOCK | QUALITY */
@Column(nullable = false, length = 32)
private String family;
/** RATIO | PCT | DAYS | INDEX */
@Column(length = 16)
private String unit;
/** Which upstream table it derives from — AGMARKNET, CLIMATE, LEDGER, CBS, UPI. */
@Column(length = 32)
private String sourceKind;
/** Beyond this age the value must not be acted on. Null means it never goes stale. */
private Integer stalenessToleranceDays;
/** HIGHER_IS_WORSE | LOWER_IS_WORSE */
@Column(length = 24)
private String direction;
@Column(length = 512)
private String derivation;
private Boolean active;
private LocalDateTime updatedAt;
@PrePersist
@PreUpdate
void stamp() {
if (active == null) active = Boolean.TRUE;
updatedAt = LocalDateTime.now();
}
}