From 27cb2efbea5157f44d4d96f30874d39b12bb36b8 Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux <hugo@trentesaux.fr> Date: Mon, 6 May 2024 17:18:09 +0200 Subject: [PATCH] wip tx comments --- README.md | 3 +- doc/edit-database.md | 11 +++ .../tables/public_transaction_comments.yaml | 3 + .../databases/default/tables/tables.yaml | 1 + .../default/1715007055748_squashed/down.sql | 21 +++++ .../default/1715007055748_squashed/up.sql | 19 ++++ src/cesium-plus.ts | 3 +- src/consts.ts | 4 + src/indexer/database.ts | 92 ++++++++++++------- src/types.ts | 7 ++ 10 files changed, 128 insertions(+), 36 deletions(-) create mode 100644 doc/edit-database.md create mode 100644 hasura/metadata/databases/default/tables/public_transaction_comments.yaml create mode 100644 hasura/migrations/default/1715007055748_squashed/down.sql create mode 100644 hasura/migrations/default/1715007055748_squashed/up.sql diff --git a/README.md b/README.md index 32b2f96..b652c9c 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ More detail in the doc below. - [start the indexer](./doc/start-indexer.md) (dev mode) - [using dev tool](./doc/using-dev-tool.md) (for debugging) - [importing cesium plus data](./doc/cesium-plus-import.md) (advanced) +- [edit the database](./doc/edit-database.md) (dev) ## TODO @@ -87,7 +88,7 @@ Features - [ ] make the app build in prod mode - [ ] allow connecting the app to a custom RPC endpoint - [ ] manage unpin requests when user/admin wants to delete data, see refcount -- [ ] document dev database change with tracking hasura console and squashing migrations +- [x] document dev database change with tracking hasura console and squashing migrations - [ ] add transaction comment - [ ] add version history to database (history of index request CIDs) -> not systematic - [ ] update description of pubkey field to ss58 diff --git a/doc/edit-database.md b/doc/edit-database.md new file mode 100644 index 0000000..3d50a6f --- /dev/null +++ b/doc/edit-database.md @@ -0,0 +1,11 @@ +# Edit database + +This is how to change something to the database structure: + +```sh +# start hasura console that tracks database changes +pnpm hasura console +# do your stuff graphically... +# squash the changes for a cleaner commit history +pnpm hasura migrate squash --from 1712826828679 +``` diff --git a/hasura/metadata/databases/default/tables/public_transaction_comments.yaml b/hasura/metadata/databases/default/tables/public_transaction_comments.yaml new file mode 100644 index 0000000..a1dde30 --- /dev/null +++ b/hasura/metadata/databases/default/tables/public_transaction_comments.yaml @@ -0,0 +1,3 @@ +table: + name: transaction_comments + schema: public diff --git a/hasura/metadata/databases/default/tables/tables.yaml b/hasura/metadata/databases/default/tables/tables.yaml index 58519d4..67e57bf 100644 --- a/hasura/metadata/databases/default/tables/tables.yaml +++ b/hasura/metadata/databases/default/tables/tables.yaml @@ -1,2 +1,3 @@ - "!include public_meta.yaml" - "!include public_profiles.yaml" +- "!include public_transaction_comments.yaml" diff --git a/hasura/migrations/default/1715007055748_squashed/down.sql b/hasura/migrations/default/1715007055748_squashed/down.sql new file mode 100644 index 0000000..60a04c4 --- /dev/null +++ b/hasura/migrations/default/1715007055748_squashed/down.sql @@ -0,0 +1,21 @@ + +comment on column "public"."transaction_comments"."time" is NULL; +ALTER TABLE "public"."transaction_comments" ALTER COLUMN "time" TYPE timestamp with time zone; + +ALTER TABLE "public"."profiles" ALTER COLUMN "time" TYPE timestamp with time zone; + +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- alter table "public"."transaction_comments" add column "time" timestamptz +-- not null; + + +comment on column "public"."transaction_comments"."comment" is NULL; + +comment on column "public"."transaction_comments"."tx_id" is NULL; + +comment on column "public"."transaction_comments"."pubkey" is NULL; + +DROP TABLE "public"."transaction_comments"; + +comment on column "public"."profiles"."pubkey" is E'base58 pubkey of profile owner'; diff --git a/hasura/migrations/default/1715007055748_squashed/up.sql b/hasura/migrations/default/1715007055748_squashed/up.sql new file mode 100644 index 0000000..ed9825a --- /dev/null +++ b/hasura/migrations/default/1715007055748_squashed/up.sql @@ -0,0 +1,19 @@ + + +comment on column "public"."profiles"."pubkey" is E'ss58 address of profile owner'; + +CREATE TABLE "public"."transaction_comments" ("index_request_cid" text NOT NULL, "pubkey" text NOT NULL, "tx_id" text NOT NULL, "comment" text NOT NULL, PRIMARY KEY ("tx_id","pubkey") , UNIQUE ("index_request_cid"));COMMENT ON TABLE "public"."transaction_comments" IS E'Transaction comments'; + +comment on column "public"."transaction_comments"."pubkey" is E'ss58 address of author'; + +comment on column "public"."transaction_comments"."tx_id" is E'transaction id in the form "blockNumber-hashStart-eventNumber"'; + +comment on column "public"."transaction_comments"."comment" is E'content of the transaction comment'; + +alter table "public"."transaction_comments" add column "time" timestamptz + not null; + +ALTER TABLE "public"."profiles" ALTER COLUMN "time" TYPE timestamp; + +ALTER TABLE "public"."transaction_comments" ALTER COLUMN "time" TYPE timestamp; +comment on column "public"."transaction_comments"."time" is E'timestamp of the index request'; diff --git a/src/cesium-plus.ts b/src/cesium-plus.ts index 9262ec2..7e3b4fe 100644 --- a/src/cesium-plus.ts +++ b/src/cesium-plus.ts @@ -2,9 +2,8 @@ import { CID } from 'multiformats' import { kubo } from './kubo' import { Buffer } from 'buffer' import { timestampToKey, arrayToVinode, mergeInodesSyncCID } from './processor' -import { type IndexRequest } from './types' import { CESIUM_PLUS_PROFILE_IMPORT } from './consts' -import type{ CplusProfile, Avatar } from './types' +import type { CplusProfile, Avatar, IndexRequest } from './types' // ========================= import functions diff --git a/src/consts.ts b/src/consts.ts index 38eb214..4259394 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -18,6 +18,10 @@ export const CESIUM_PLUS_PROFILE_IMPORT = CID.parse('bafkreiawtammeqc55cssr2zepf export const CESIUM_PLUS_PROFILE_INSERT = CID.parse('bafkreigi5phtqpo6a2f3tx4obaja4fzevy3nyvnl4bnkcxylyqnfeowzbm') export const CESIUM_PLUS_PROFILE_DELETE = CID.parse('bafkreic5bv5ytl7zv5rh5j2bd5mw6nfrn33mxhiobgmpsiu65yjw3eeduu') +// document kind for transaction comment (old ones and new ones) +export const TRANSACTION_COMMENT_V1 = 'TODO' +export const TRANSACTION_COMMENT = CID.parse('bafkreiegjt5mrfj2hshuw6koejdfiykq57mzjeprfckxj5zpxxtqj4qzeu') + // ========== // explorer resources diff --git a/src/indexer/database.ts b/src/indexer/database.ts index 335e624..aaaad26 100644 --- a/src/indexer/database.ts +++ b/src/indexer/database.ts @@ -1,9 +1,13 @@ -import { CESIUM_PLUS_PROFILE_IMPORT, CESIUM_PLUS_PROFILE_INSERT, CESIUM_PLUS_PROFILE_DELETE } from '../consts' -import type { IndexRequest } from '../types' +import { + CESIUM_PLUS_PROFILE_IMPORT, + CESIUM_PLUS_PROFILE_INSERT, + CESIUM_PLUS_PROFILE_DELETE, + TRANSACTION_COMMENT +} from '../consts' +import type { CplusProfile, IndexRequest, TxComment } from '../types' import { CID } from 'multiformats' import pg from 'pg' import { kubo } from '../kubo' -import type { CplusProfile } from '../cesium-plus' // define form env const env = { @@ -103,6 +107,29 @@ const cesiumPlusProfile: QueryBuilder = { ] } +// transaction comment query and param builder +// prevents overwrite +const txComment: QueryBuilder = { + query: `INSERT INTO + transaction_comments(index_request_cid, time, pubkey, tx_id, comment) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (pubkey, tx_id) + DO NOTHING; + `, + paramBuilder: (irCID: CID, ir: IndexRequest, _dataCID: CID, data: TxComment) => [ + // $1 index_request_cid + irCID.toString(), + // $2 time + new Date(ir.time).toISOString(), + // $3 pubkey + ir.pubkey, + // $4 tx_id + data.tx_id, + // $5 comment + data.comment + ] +} + /// return data handler for a query builder const dataHandler: <T>( q: QueryBuilder, @@ -114,50 +141,49 @@ const dataHandler: <T>( return client.query(q.query, q.paramBuilder(irCID, ir, dataCID, data)) } +// handle index request with non-null data +async function handleIrWithNonNullData<T>(irCID: CID, ir: IndexRequest, q: QueryBuilder): Promise<void> { + const dataCID = ir.data + if (dataCID == null) { + console.log('no data when required') + return + } + kubo.dag + .get(dataCID) + .then((d) => d.value) + .then(dataHandler<T>(q, irCID, ir, dataCID)) + .catch((e) => { + console.log(e) + console.log('☁️ could not get data to index ' + dataCID) + }) +} + // insert index request in database export async function handleInsertRequest(irCID: CID, ir: IndexRequest) { console.log('💾 indexing ' + irCID) switch (ir.kind.toString()) { - // insert index request - case CESIUM_PLUS_PROFILE_INSERT.toString(): { - const dataCID = ir.data - if (dataCID == null) { - console.log('no data when required') - return - } - await kubo.dag - .get(dataCID) - .then((d) => d.value) - .then(dataHandler<CplusProfile>(cesiumPlusProfile, irCID, ir, dataCID)) - .catch((e) => { - console.log(e) - console.log('☁️ could not get data to index ' + dataCID) - }) + // insert cesium plus profile + case CESIUM_PLUS_PROFILE_INSERT.toString(): + handleIrWithNonNullData<CplusProfile>(irCID, ir, cesiumPlusProfile) break - } // insert cesium plus import - case CESIUM_PLUS_PROFILE_IMPORT.toString(): { - const dataCID = ir.data - if (dataCID == null) { - console.log('no data when required') - return - } + case CESIUM_PLUS_PROFILE_IMPORT.toString(): // transform base58 pubkey to ss58 address with gdev prefix ir.pubkey = base58ToSS58(ir.pubkey, GDEV_PREFIX) - await kubo.dag - .get(dataCID) - .then((d) => d.value) - .then(dataHandler<CplusProfile>(cesiumPlusProfile, irCID, ir, dataCID)) + handleIrWithNonNullData<CplusProfile>(irCID, ir, cesiumPlusProfile) break - } - // delete - case CESIUM_PLUS_PROFILE_DELETE.toString(): { + // delete cesium plus profile + case CESIUM_PLUS_PROFILE_DELETE.toString(): await client.query(`DELETE FROM profiles WHERE pubkey = $1;`, [ir.pubkey]) break - } + + // insert transaction comment + case TRANSACTION_COMMENT.toString(): + handleIrWithNonNullData<TxComment>(irCID, ir, txComment) + break // unimplemented default: diff --git a/src/types.ts b/src/types.ts index 628af26..46b4274 100644 --- a/src/types.ts +++ b/src/types.ts @@ -122,3 +122,10 @@ interface Geoloc { lat: number lon: number } + +// ================== tx comment + +export interface TxComment { + tx_id: string + comment: string +} -- GitLab