Tasks goals: auto metrics (tasks.goals.metric_key/metric_detail/metric_computed_at, tasks.metric_sources cache). €10k/month goal gets a live progress bar: Revolut recurring income (excl. Zorgtoeslag/Joint) computed on page load + trailing-12m paid Moneybird invoices / 12 cached by a daily goal-metrics user timer; stacked bar with %, amount vs target, salary/side-income breakdown, last-updated
Some checks failed
Deploy production / deploy (push) Failing after 1m14s
Some checks failed
Deploy production / deploy (push) Failing after 1m14s
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
date,
|
||||
index,
|
||||
integer,
|
||||
jsonb,
|
||||
numeric,
|
||||
smallint,
|
||||
text,
|
||||
@@ -14,6 +15,7 @@ import {
|
||||
} from 'drizzle-orm/pg-core';
|
||||
import { tasksSchema } from './schemas';
|
||||
import { id, timestamps, timestamptz } from './helpers';
|
||||
import type { GoalMetricDetail } from '../../goal-metrics/core';
|
||||
|
||||
// Private task + goal tracker (owner only, see requireOwner); meant to replace TickTick.
|
||||
// No user_id: there is exactly one owner, and the schema is granted to personal_app only.
|
||||
@@ -60,6 +62,10 @@ export const todoGoals = tasksSchema.table(
|
||||
metricUnit: text('metric_unit'), // e.g. "EUR"
|
||||
metricTarget: numeric('metric_target', { precision: 14, scale: 2, mode: 'number' }),
|
||||
metricCurrent: numeric('metric_current', { precision: 14, scale: 2, mode: 'number' }),
|
||||
// Auto metric (src/lib/server/goal-metrics): when set, metric_current is computed, not typed.
|
||||
metricKey: text('metric_key'),
|
||||
metricDetail: jsonb('metric_detail').$type<GoalMetricDetail>(), // breakdown of the last computation
|
||||
metricComputedAt: timestamptz('metric_computed_at'),
|
||||
flagged: boolean('flagged').notNull().default(false),
|
||||
sortOrder: integer('sort_order').notNull().default(0),
|
||||
source: text('source'), // e.g. 'daisy-import', 'manual', 'ticktick'
|
||||
@@ -73,6 +79,17 @@ export const todoGoals = tasksSchema.table(
|
||||
]
|
||||
);
|
||||
|
||||
/** Cached inputs for auto goal metrics that come from slow/external APIs (e.g. Moneybird),
|
||||
* refreshed daily by scripts/goal-metrics.ts so page loads never call them. */
|
||||
export const todoMetricSources = tasksSchema.table('metric_sources', {
|
||||
key: text('key').primaryKey(),
|
||||
value: numeric('value', { precision: 14, scale: 2, mode: 'number' }),
|
||||
detail: jsonb('detail'),
|
||||
computedAt: timestamptz('computed_at').notNull().defaultNow(), // last successful refresh
|
||||
attemptedAt: timestamptz('attempted_at').notNull().defaultNow(),
|
||||
error: text('error') // last refresh error (value stays the last good one)
|
||||
});
|
||||
|
||||
export const todoTasks = tasksSchema.table(
|
||||
'tasks',
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user