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>
71 lines
2.0 KiB
Java
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();
|
|
}
|
|
}
|