🐋 Docker volume for Sqlite
Some checks failed
Deploy application / deploy (push) Failing after 7s

- Moved database to subdir specified by env
- Default data dir /data
- Move loggers to cronJob onTick
- Added volume for data dir in Docker compose
- Create any missing dir specified by env
This commit is contained in:
2025-01-26 19:29:43 +01:00
parent aaa85e99cb
commit 9850017e3a
8 changed files with 34 additions and 23 deletions

View File

@ -17,8 +17,8 @@ export type TokenResponseRaw = {
export type TokenKey = "access-token" | "refresh-token"
export function createDb(filename: string) {
const db = new Database(filename)
export function createDb(filepath: string) {
const db = new Database(filepath)
db.pragma("journal_mode = WAL")
db.exec(
"CREATE TABLE IF NOT EXISTS tokens ('key' VARCHAR PRIMARY KEY, token VARCHAR NOT NULL, expires_at DATETIME NOT NULL)",

View File

@ -93,6 +93,7 @@ export class Sparebank1Impl implements Sparebank1 {
async transactionsPastDay(
...accountKeys: ReadonlyArray<string>
): Promise<TransactionResponse> {
// TODO API is inclusive, today should equal lastDay
const today = dayjs()
const lastDay = today.subtract(1, "day")
return await Api.transactions(await this.getAccessToken(), accountKeys, {

View File

@ -1,4 +1,5 @@
import { CronJob } from "cron"
import logger from "@/logger.ts"
/**
* Run a function every day at 1 AM, Oslo time.
@ -8,7 +9,11 @@ import { CronJob } from "cron"
export function cronJobDaily(onTick: () => Promise<void>): CronJob {
return CronJob.from({
cronTime: "0 0 1 * * *",
onTick,
onTick: async () => {
logger.info("Starting daily job")
await onTick()
logger.info("Finished daily job")
},
start: true,
timeZone: "Europe/Oslo",
})

View File

@ -10,6 +10,7 @@ import {
ACTUAL_ACCOUNT_IDS,
ACTUAL_DATA_DIR,
BANK_ACCOUNT_IDS,
DB_DIRECTORY,
DB_FILENAME,
} from "../config.ts"
import logger from "@/logger.ts"
@ -19,10 +20,9 @@ import * as fs from "node:fs"
import { CronJob } from "cron"
// TODO Transports api for pino https://github.com/pinojs/pino/blob/HEAD/docs/transports.md
// TODO create Dockerfile and docker-compose.yml
// TODO Gitea workflow
// TODO move tsx to devDependency. Requires ts support for Node with support for @ alias
// TODO global exception handler, log and graceful shutdown
// TODO verbatimSyntax in tsconfig, conflicts with jest
export async function daily(actual: Actual, bank: Bank): Promise<void> {
// Fetch transactions from the bank
@ -60,22 +60,23 @@ async function fetchTransactionsFromPastDay(
return response.transactions
}
function createCacheDirIfMissing(): void {
if (!fs.existsSync(ACTUAL_DATA_DIR)) {
logger.info(`Missing '${ACTUAL_DATA_DIR}', creating...`)
fs.mkdirSync(ACTUAL_DATA_DIR)
function createDirIfMissing(directory: string): void {
if (!fs.existsSync(directory)) {
logger.info(`Missing '${directory}', creating...`)
fs.mkdirSync(directory, { recursive: true })
}
}
async function main(): Promise<void> {
logger.info("Starting application")
createCacheDirIfMissing()
createDirIfMissing(ACTUAL_DATA_DIR)
createDirIfMissing(DB_DIRECTORY)
const actual = await ActualImpl.init()
const databaseFileName = `${DB_FILENAME}.sqlite`
const db = createDb(databaseFileName)
logger.info(`Started SQLlite database with filename="${databaseFileName}"`)
const databaseFilePath = `${DB_DIRECTORY}/${DB_FILENAME}.sqlite`
const db = createDb(databaseFilePath)
logger.info(`Started Sqlite database at '${databaseFilePath}'`)
const bank = new Sparebank1Impl(db)
process.on("SIGINT", async () => {
@ -91,14 +92,10 @@ async function main(): Promise<void> {
}
logger.info("Waiting for CRON job to start")
cronJob = cronJobDaily(async () => {
logger.info("Running daily job")
await daily(actual, bank)
logger.info("Finished daily job")
})
cronJob = cronJobDaily(async () => await daily(actual, bank))
async function shutdown(): Promise<void> {
logger.info("Shutting down")
logger.info("Shutting down, Bye!")
await actual.shutdown()
db.close()
cronJob?.stop()