commit c3ca613d0131185e4a661a388323cf5ce045e050
parent 8a2ffb58b5cd338c373c626d7fde0def8501ba77
Author: mtmn <miro@haravara.org>
Date: Mon, 13 Apr 2026 01:07:27 +0200
chore: install pre-commit hooks
Diffstat:
5 files changed, 63 insertions(+), 41 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
@@ -0,0 +1,23 @@
+---
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v6.0.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: double-quote-string-fixer
+
+ - repo: https://github.com/biomejs/pre-commit
+ rev: v2.4.11
+ hooks:
+ - id: biome-format
+
+ - repo: https://github.com/gitleaks/gitleaks
+ rev: v8.30.1
+ hooks:
+ - id: gitleaks
+
+ - repo: https://github.com/astro/deadnix
+ rev: v1.3.1
+ hooks:
+ - id: deadnix
diff --git a/devenv.lock b/devenv.lock
@@ -62,4 +62,4 @@
},
"root": "root",
"version": 7
-}
-\ No newline at end of file
+}
diff --git a/docs/duckdb.md b/docs/duckdb.md
@@ -31,7 +31,7 @@ Stores enriched metadata fetched from MusicBrainz, Last.fm, and Discogs.
## Application Usage
-The application interacts with DuckDB via a PureScript FFI layer (`src/Db.js` and `src/Db.purs`).
+The application interacts with DuckDB via a PureScript FFI layer (`src/Db.js` and `src/Db.purs`).
- **BigInt Handling**: Since DuckDB returns `BIGINT` as JavaScript `BigInt`, the FFI layer converts these to `Number` to ensure compatibility with standard JSON serialization.
- **Background Enrichment**: The server identifies "unenriched" scrobbles (those with an MBID but no metadata) and performs background updates to the `release_metadata` table.
@@ -50,8 +50,8 @@ LIMIT 10;
### Listening Activity by Hour
```sql
-SELECT
- extract('hour' from to_timestamp(listened_at)) as hour,
+SELECT
+ extract('hour' from to_timestamp(listened_at)) as hour,
count(*) as count
FROM scrobbles
GROUP BY hour
@@ -70,7 +70,7 @@ ORDER BY count DESC;
### MBID Enrichment Coverage
```sql
-SELECT
+SELECT
count(*) as total,
count(release_mbid) FILTER (WHERE release_mbid != '') as with_mbid,
(count(release_mbid) FILTER (WHERE release_mbid != '')::FLOAT / count(*)) * 100 as percentage
diff --git a/docs/duckdb_queries.md b/docs/duckdb_queries.md
@@ -51,8 +51,8 @@ LIMIT 10;
### Scrobbles per day (Last 30 days)
```sql
-SELECT
- to_timestamp(listened_at)::DATE as date,
+SELECT
+ to_timestamp(listened_at)::DATE as date,
count(*) as count
FROM scrobbles
WHERE to_timestamp(listened_at) > now() - INTERVAL '30 days'
@@ -62,8 +62,8 @@ ORDER BY date DESC;
### Scrobbles per month
```sql
-SELECT
- date_trunc('month', to_timestamp(listened_at)) as month,
+SELECT
+ date_trunc('month', to_timestamp(listened_at)) as month,
count(*) as count
FROM scrobbles
GROUP BY month
@@ -72,8 +72,8 @@ ORDER BY month DESC;
### Listening activity by hour of day
```sql
-SELECT
- extract('hour' from to_timestamp(listened_at)) as hour,
+SELECT
+ extract('hour' from to_timestamp(listened_at)) as hour,
count(*) as count
FROM scrobbles
GROUP BY hour
@@ -82,8 +82,8 @@ ORDER BY hour;
### Most active day of the week
```sql
-SELECT
- dayname(to_timestamp(listened_at)) as day,
+SELECT
+ dayname(to_timestamp(listened_at)) as day,
count(*) as count
FROM scrobbles
GROUP BY day, dayofweek(to_timestamp(listened_at))
@@ -102,9 +102,9 @@ HAVING count(*) > 1;
### Recent scrobbles with human-readable timestamps
```sql
-SELECT
- to_timestamp(listened_at) as time,
- artist_name,
+SELECT
+ to_timestamp(listened_at) as time,
+ artist_name,
track_name
FROM scrobbles
ORDER BY listened_at DESC
@@ -113,7 +113,7 @@ LIMIT 20;
### Check MBID coverage
```sql
-SELECT
+SELECT
count(*) as total,
count(release_mbid) FILTER (WHERE release_mbid != '') as with_mbid,
(count(release_mbid) FILTER (WHERE release_mbid != '')::FLOAT / count(*)) * 100 as percentage
diff --git a/package.json b/package.json
@@ -1,25 +1,25 @@
{
- "name": "scorpus",
- "version": "1.0.0",
- "description": "ListenBrainz frontend in PureScript",
- "main": "index.js",
- "type": "module",
- "scripts": {
- "build": "npx spago build && npx esbuild output/Main/index.js --bundle --platform=node --format=esm --footer:js='main();' --outfile=server.js --external:http --external:https --external:dotenv --external:url --external:duckdb --external:@aws-sdk/client-s3 && npx spago bundle --module Client --outfile client.js --platform browser",
- "test": "npx spago test",
- "tidy": "purs-tidy format-in-place src/**/*.purs"
- },
- "devDependencies": {
- "esbuild": "^0.28.0",
- "purescript": "^0.15.16",
- "purescript-language-server": "^0.18.0",
- "purescript-psa": "^0.9.0",
- "purs-tidy": "^0.11.1",
- "spago": "^1.0.4"
- },
- "dependencies": {
- "@aws-sdk/client-s3": "^3.1029.0",
- "dotenv": "^17.4.1",
- "duckdb": "^1.4.4"
- }
+ "name": "scorpus",
+ "version": "1.0.0",
+ "description": "ListenBrainz frontend in PureScript",
+ "main": "index.js",
+ "type": "module",
+ "scripts": {
+ "build": "npx spago build && npx esbuild output/Main/index.js --bundle --platform=node --format=esm --footer:js='main();' --outfile=server.js --external:http --external:https --external:dotenv --external:url --external:duckdb --external:@aws-sdk/client-s3 && npx spago bundle --module Client --outfile client.js --platform browser",
+ "test": "npx spago test",
+ "tidy": "purs-tidy format-in-place src/**/*.purs"
+ },
+ "devDependencies": {
+ "esbuild": "^0.28.0",
+ "purescript": "^0.15.16",
+ "purescript-language-server": "^0.18.0",
+ "purescript-psa": "^0.9.0",
+ "purs-tidy": "^0.11.1",
+ "spago": "^1.0.4"
+ },
+ "dependencies": {
+ "@aws-sdk/client-s3": "^3.1029.0",
+ "dotenv": "^17.4.1",
+ "duckdb": "^1.4.4"
+ }
}