From c6c0d096c1d5cd91d1ba5d12f48ef5fe0ae7a6f6 Mon Sep 17 00:00:00 2001 From: jmgasper Date: Thu, 27 Aug 2026 10:08:33 +1000 Subject: [PATCH 1/2] Forum post count to challenge response --- .github/workflows/trivy.yaml | 44 +++++++++++++++++++++++++ packages/forums-prisma-client/README.md | 27 +++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/trivy.yaml diff --git a/.github/workflows/trivy.yaml b/.github/workflows/trivy.yaml new file mode 100644 index 0000000..9706c0a --- /dev/null +++ b/.github/workflows/trivy.yaml @@ -0,0 +1,44 @@ +name: Trivy Scanner + +permissions: + actions: read + contents: read + security-events: write + +on: + push: + branches: + - main + - master + - dev + - develop + pull_request: + workflow_dispatch: + +jobs: + trivy-scan: + name: Trivy SAST and SCA + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run Trivy scanner in repo mode + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 + with: + version: "v0.73.0" + scan-type: "fs" + scan-ref: "." + ignore-unfixed: true + format: "sarif" + output: "trivy-results.sarif" + severity: "CRITICAL,HIGH,UNKNOWN" + limit-severities-for-sarif: true + scanners: "vuln,secret,misconfig,license" + github-pat: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload Trivy scan results to GitHub Security tab + if: always() + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: "trivy-results.sarif" diff --git a/packages/forums-prisma-client/README.md b/packages/forums-prisma-client/README.md index 790df72..e31401b 100644 --- a/packages/forums-prisma-client/README.md +++ b/packages/forums-prisma-client/README.md @@ -1,5 +1,28 @@ # Forums Prisma Client -Generated output path for the exported forums Prisma client generated from `prisma/schema.prisma`. +Reusable Prisma client generated from `prisma/schema.prisma` for services that +need direct, typed access to forum data. -The Batch 1 scaffold intentionally does not define forum domain models. The generated client is ready for imports and will expose forum models after later batches add the final schema. +The package exports the Forums `Topic`, `Post`, `TopicClosure`, `TopicWatch`, +`TopicReadState`, `MemberBan`, and `IpBan` models. Consumers import this client +from the Forums API package and must supply the Prisma 7 PostgreSQL driver +adapter required by their runtime: + +```ts +import { PrismaClient } from '@topcoder/forums-api-v6/packages/forums-prisma-client'; +import { PrismaPg } from '@prisma/adapter-pg'; + +const forumsDbUrl = process.env.FORUMS_DB_URL; +if (!forumsDbUrl) { + throw new Error('FORUMS_DB_URL is required'); +} +const adapter = new PrismaPg( + { connectionString: forumsDbUrl }, + { schema: 'forums' }, +); +const forums = new PrismaClient({ adapter }); +``` + +The caller owns the client lifecycle and must call `$disconnect()` during +shutdown. Regenerate this package with `pnpm prisma:generate` whenever the +Forums Prisma schema changes. From 90bc204bb2386592ff0b00d285369d8fc2da9420 Mon Sep 17 00:00:00 2001 From: jmgasper Date: Thu, 27 Aug 2026 13:03:35 +1000 Subject: [PATCH 2/2] Support for reactions --- README.md | 13 +- packages/forums-prisma-client/README.md | 8 +- packages/forums-prisma-client/edge.js | 22 +- .../forums-prisma-client/index-browser.js | 14 +- packages/forums-prisma-client/index.d.ts | 1748 ++++++++++++++++- packages/forums-prisma-client/index.js | 22 +- packages/forums-prisma-client/package.json | 2 +- packages/forums-prisma-client/schema.prisma | 25 +- .../migration.sql | 22 + prisma/schema.prisma | 25 +- src/forums/dto/forums-command-response.dto.ts | 25 + src/forums/dto/forums-command.dto.ts | 17 + src/forums/dto/forums-read.dto.ts | 18 + src/forums/forums-command.service.spec.ts | 99 +- src/forums/forums-command.service.ts | 165 +- ...rums-notification-read.integration.spec.ts | 178 +- src/forums/forums-read-query.service.ts | 30 +- src/forums/forums-read.service.ts | 10 + src/forums/posts.controller.ts | 111 +- src/main.ts | 2 +- 20 files changed, 2461 insertions(+), 95 deletions(-) create mode 100644 prisma/migrations/20260827120000_post_reactions/migration.sql diff --git a/README.md b/README.md index 0ac3db7..eeddda6 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ and post-commit watch notifications. - `PUT /v6/forums/topics/:topicId/read-state` - `PATCH /v6/forums/posts/:postId` - `DELETE /v6/forums/posts/:postId` +- `PUT /v6/forums/posts/:postId/reaction` +- `DELETE /v6/forums/posts/:postId/reaction` - `PUT /v6/forums/moderation/topics/:topicId/lock` - `DELETE /v6/forums/moderation/topics/:topicId/lock` - `PUT /v6/forums/moderation/member-bans/:memberId` @@ -28,9 +30,11 @@ and post-commit watch notifications. - `PUT /v6/forums/moderation/ip-bans/:ipAddress` - `DELETE /v6/forums/moderation/ip-bans/:ipAddress` -This service includes the forums schema, Prisma client export, topic read workflows, transactional command-side workflows, centralized forums authorization and runtime moderation for topics, posts, watches, and explicit read-state updates, plus best-effort watch notification publishing for new posts and successful allowed child-topic starter posts. The policy resolves inherited topic restrictions, challenge access, resource-role/copilot elevation, role matching, ownership, scoped M2M write access, and M2M on-behalf target-member visibility before writes, reads, or notification delivery. Runtime moderation enforces active member bans, trusted exact-IP bans for human request traffic, and locked-topic mutation rules. +This service includes the forums schema, Prisma client export, topic read workflows, transactional command-side workflows, per-member post reactions, centralized forums authorization and runtime moderation for topics, posts, watches, and explicit read-state updates, plus best-effort watch notification publishing for new posts and successful allowed child-topic starter posts. The policy resolves inherited topic restrictions, challenge access, resource-role/copilot elevation, role matching, ownership, scoped M2M write access, and M2M on-behalf target-member visibility before writes, reads, or notification delivery. Runtime moderation enforces active member bans, trusted exact-IP bans for human request traffic, and locked-topic mutation rules. -Topic reads are exposed under `read:forums-topics`. `GET /v6/forums/topics` returns visible non-challenge root topics; `GET /v6/forums/topics/challenges/:challengeId` checks base challenge visibility before returning visible challenge roots; `GET /v6/forums/topics/:topicId/children` requires parent visibility before filtering direct children; and `GET /v6/forums/topics/:topicId` returns topic detail with an embedded post tree. Active member bans and trusted exact-IP bans return 403 before read policy or query work. Topic summaries include `locked`, `lockedBy`, and `lockedAt`; `lockedBy` and `lockedAt` may be null for imported legacy locked topics. Locked topics remain readable for callers that otherwise pass moderation and visibility checks. Detail embeds posts under `read:forums-topics`, keeps deleted post placeholders with null content, counts only non-deleted posts, and derives unread state from `TopicReadState.lastReadAt`. `read:forums-posts` remains reserved for future post-specific read APIs in v1. +Topic reads are exposed under `read:forums-topics`. `GET /v6/forums/topics` returns visible non-challenge root topics; `GET /v6/forums/topics/challenges/:challengeId` checks base challenge visibility before returning visible challenge roots; `GET /v6/forums/topics/:topicId/children` requires parent visibility before filtering direct children; and `GET /v6/forums/topics/:topicId` returns topic detail with an embedded post tree. Active member bans and trusted exact-IP bans return 403 before read policy or query work. Topic summaries include `locked`, `lockedBy`, and `lockedAt`; `lockedBy` and `lockedAt` may be null for imported legacy locked topics. Locked topics remain readable for callers that otherwise pass moderation and visibility checks. Detail embeds posts under `read:forums-topics`, keeps deleted post placeholders with null content, counts only non-deleted posts, derives unread state from `TopicReadState.lastReadAt`, and includes each post's shared `thumbsUpCount`/`thumbsDownCount` plus the authenticated member's nullable `viewerReaction`. `read:forums-posts` remains reserved for future post-specific read APIs in v1. + +Human members set or switch their one-per-post reaction with `PUT /v6/forums/posts/:postId/reaction` and `{ "reaction": "THUMBS_UP" }` or `{ "reaction": "THUMBS_DOWN" }`. `DELETE` on the same route idempotently removes the member's reaction. Both commands return the resulting `viewerReaction` and current shared counts, enforce runtime bans and inherited post visibility, and reject deleted posts. They remain available on locked topics because reactions do not change discussion content. The reaction routes are human-member-only; M2M callers cannot own reaction state. Top-level non-challenge topics may be created by human admins and scoped M2M callers. Top-level challenge topics may be created by eligible challenge members, challenge copilots, and admins; M2M callers cannot create challenge roots. Regular authenticated members may create child topics only under parents they can see and only when the resolved effective child context remains non-challenge; requests that inherit or introduce a non-null `challengeId` under a parent are rejected before writes. Allowed child topics must keep monotonic role restrictions: inherited roles cannot be cleared or replaced. Challenge-scoped visibility is verified through the configured challenge and resource adapters, including challenge-resource membership and challenge-copilot elevation. Challenge copilots may access or moderate challenge-scoped forums only when any effective `roleName` forum restriction is also satisfied; admin and scoped M2M bypass behavior is unchanged. Active member bans and trusted exact-IP bans return 403 for human writes before content, watch, or read-state changes. M2M on-behalf watch and read-state commands enforce active bans on the resolved target member and do not evaluate IP bans. Locked topics reject child-topic creation under the locked parent, replies, topic updates/deletes, and post updates/deletes unless the actor is an administrator or a human challenge copilot acting on a challenge-scoped topic. @@ -158,7 +162,8 @@ Active `MemberBan` rows return 403 for reads, writes, human watch/read-state commands, and M2M on-behalf watch/read-state commands targeting that member. Active `IpBan` rows return 403 only for non-M2M requests with a trusted resolved client IP; exact matching is performed by PostgreSQL `inet` equality. Locked -topics remain listable and readable but reject discussion mutations. Lock bypass +topics remain listable and readable but reject discussion content mutations. +Post reactions remain available to otherwise-authorized human members. Lock bypass is limited to administrators everywhere and human challenge copilots on challenge-scoped topics. Scoped M2M callers do not bypass locks unless they also qualify as administrators. @@ -223,6 +228,6 @@ interrupted, wipe the target forums dataset and rerun the full import. ## Prisma -The forums Prisma schema defines `Topic`, `Post`, `TopicClosure`, `TopicWatch`, `TopicReadState`, `MemberBan`, and `IpBan` in the dedicated `forums` schema. Topics store an explicit lock state plus nullable lock timestamp and lock actor member id. Ban rows keep active and removed audit metadata; the migration enforces one active row per member or exact IP value and validates IP bans as single IPv4/IPv6 host values. `pnpm prisma:generate` emits the local client at `prisma/generated/client` and the reusable exported client at `packages/forums-prisma-client`. +The forums Prisma schema defines `Topic`, `Post`, `PostReaction`, `TopicClosure`, `TopicWatch`, `TopicReadState`, `MemberBan`, and `IpBan` in the dedicated `forums` schema. `PostReaction` uses a composite post/member key so each member has at most one thumbs-up or thumbs-down value per post; deleting a post cascades its reactions. Topics store an explicit lock state plus nullable lock timestamp and lock actor member id. Ban rows keep active and removed audit metadata; the migration enforces one active row per member or exact IP value and validates IP bans as single IPv4/IPv6 host values. `pnpm prisma:generate` emits the local client at `prisma/generated/client` and the reusable exported client at `packages/forums-prisma-client`. Topic creation is transactional: it creates the topic, starter post, closure rows, and, for human authors, author watch and read-state rows together. M2M topic creation uses the system author and skips member watch/read-state side effects. Topic deletion is soft deletion, and post deletion preserves the post row while setting content to null for placeholder reads. Topic summary reads use side-effect-free raw queries for topic lock state, visible-post counts, nullable latest visible activity, and unread derivation, then apply centralized forums policy filtering before pagination. diff --git a/packages/forums-prisma-client/README.md b/packages/forums-prisma-client/README.md index e31401b..e08e727 100644 --- a/packages/forums-prisma-client/README.md +++ b/packages/forums-prisma-client/README.md @@ -3,10 +3,10 @@ Reusable Prisma client generated from `prisma/schema.prisma` for services that need direct, typed access to forum data. -The package exports the Forums `Topic`, `Post`, `TopicClosure`, `TopicWatch`, -`TopicReadState`, `MemberBan`, and `IpBan` models. Consumers import this client -from the Forums API package and must supply the Prisma 7 PostgreSQL driver -adapter required by their runtime: +The package exports the Forums `Topic`, `Post`, `PostReaction`, +`PostReactionType`, `TopicClosure`, `TopicWatch`, `TopicReadState`, `MemberBan`, +and `IpBan` models. Consumers import this client from the Forums API package and +must supply the Prisma 7 PostgreSQL driver adapter required by their runtime: ```ts import { PrismaClient } from '@topcoder/forums-api-v6/packages/forums-prisma-client'; diff --git a/packages/forums-prisma-client/edge.js b/packages/forums-prisma-client/edge.js index f9a3f04..efe60b3 100644 --- a/packages/forums-prisma-client/edge.js +++ b/packages/forums-prisma-client/edge.js @@ -142,6 +142,14 @@ exports.Prisma.PostScalarFieldEnum = { deletedByMemberId: 'deletedByMemberId' }; +exports.Prisma.PostReactionScalarFieldEnum = { + postId: 'postId', + memberId: 'memberId', + reaction: 'reaction', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +}; + exports.Prisma.TopicClosureScalarFieldEnum = { ancestorTopicId: 'ancestorTopicId', descendantTopicId: 'descendantTopicId', @@ -175,13 +183,17 @@ exports.Prisma.NullsOrder = { first: 'first', last: 'last' }; - +exports.PostReactionType = exports.$Enums.PostReactionType = { + THUMBS_UP: 'THUMBS_UP', + THUMBS_DOWN: 'THUMBS_DOWN' +}; exports.Prisma.ModelName = { Topic: 'Topic', MemberBan: 'MemberBan', IpBan: 'IpBan', Post: 'Post', + PostReaction: 'PostReaction', TopicClosure: 'TopicClosure', TopicWatch: 'TopicWatch', TopicReadState: 'TopicReadState' @@ -194,14 +206,14 @@ const config = { "clientVersion": "7.9.0", "engineVersion": "e922089b7d7502aff4249d5da3420f6fa55fc6ad", "activeProvider": "postgresql", - "inlineSchema": "generator client {\n provider = \"prisma-client-js\"\n output = \"./generated/client\"\n}\n\ngenerator externalClient {\n provider = \"prisma-client-js\"\n output = \"../packages/forums-prisma-client\"\n binaryTargets = [\"native\", \"debian-openssl-3.0.x\"]\n}\n\ndatasource db {\n provider = \"postgresql\"\n schemas = [\"forums\"]\n}\n\nmodel Topic {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n parentTopicId String? @db.VarChar(14)\n challengeId String? @db.VarChar(64)\n roleName String? @db.VarChar(128)\n title String @db.VarChar(255)\n isAnnouncement Boolean @default(false)\n locked Boolean @default(false)\n lockedAt DateTime?\n lockedByMemberId String? @db.VarChar(64)\n authorMemberId String @db.VarChar(64)\n authorHandle String @db.VarChar(128)\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n deletedAt DateTime?\n deletedByMemberId String? @db.VarChar(64)\n\n parentTopic Topic? @relation(\"TopicChildren\", fields: [parentTopicId], references: [id])\n childTopics Topic[] @relation(\"TopicChildren\")\n posts Post[]\n ancestorClosures TopicClosure[] @relation(\"TopicClosureAncestor\")\n descendantClosures TopicClosure[] @relation(\"TopicClosureDescendant\")\n watches TopicWatch[]\n readStates TopicReadState[]\n\n @@index([parentTopicId])\n @@index([challengeId])\n @@index([roleName])\n @@index([deletedAt])\n @@index([isAnnouncement, createdAt])\n @@schema(\"forums\")\n}\n\nmodel MemberBan {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n memberId String @db.VarChar(64)\n createdAt DateTime @default(now())\n createdByMemberId String? @db.VarChar(64)\n removedAt DateTime?\n removedByMemberId String? @db.VarChar(64)\n\n @@index([memberId])\n @@index([removedAt])\n @@schema(\"forums\")\n}\n\nmodel IpBan {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n ipAddress String @db.VarChar(45)\n createdAt DateTime @default(now())\n createdByMemberId String? @db.VarChar(64)\n removedAt DateTime?\n removedByMemberId String? @db.VarChar(64)\n\n @@index([ipAddress])\n @@index([removedAt])\n @@schema(\"forums\")\n}\n\nmodel Post {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n topicId String @db.VarChar(14)\n parentType String @db.VarChar(16)\n parentId String @db.VarChar(14)\n authorMemberId String @db.VarChar(64)\n authorHandle String @db.VarChar(128)\n content String? @db.Text\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n deletedAt DateTime?\n deletedByMemberId String? @db.VarChar(64)\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@index([topicId, createdAt])\n @@index([topicId, parentType, parentId])\n @@index([deletedAt])\n @@schema(\"forums\")\n}\n\nmodel TopicClosure {\n ancestorTopicId String @db.VarChar(14)\n descendantTopicId String @db.VarChar(14)\n depth Int\n\n ancestorTopic Topic @relation(\"TopicClosureAncestor\", fields: [ancestorTopicId], references: [id], onDelete: Cascade)\n descendantTopic Topic @relation(\"TopicClosureDescendant\", fields: [descendantTopicId], references: [id], onDelete: Cascade)\n\n @@id([ancestorTopicId, descendantTopicId])\n @@index([ancestorTopicId, depth])\n @@index([descendantTopicId, depth])\n @@schema(\"forums\")\n}\n\nmodel TopicWatch {\n topicId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n createdAt DateTime @default(now())\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@id([topicId, memberId])\n @@index([memberId])\n @@schema(\"forums\")\n}\n\nmodel TopicReadState {\n topicId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n lastReadAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@id([topicId, memberId])\n @@index([memberId])\n @@index([lastReadAt])\n @@schema(\"forums\")\n}\n" + "inlineSchema": "generator client {\n provider = \"prisma-client-js\"\n output = \"./generated/client\"\n}\n\ngenerator externalClient {\n provider = \"prisma-client-js\"\n output = \"../packages/forums-prisma-client\"\n binaryTargets = [\"native\", \"debian-openssl-3.0.x\"]\n}\n\ndatasource db {\n provider = \"postgresql\"\n schemas = [\"forums\"]\n}\n\nenum PostReactionType {\n THUMBS_UP\n THUMBS_DOWN\n\n @@schema(\"forums\")\n}\n\nmodel Topic {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n parentTopicId String? @db.VarChar(14)\n challengeId String? @db.VarChar(64)\n roleName String? @db.VarChar(128)\n title String @db.VarChar(255)\n isAnnouncement Boolean @default(false)\n locked Boolean @default(false)\n lockedAt DateTime?\n lockedByMemberId String? @db.VarChar(64)\n authorMemberId String @db.VarChar(64)\n authorHandle String @db.VarChar(128)\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n deletedAt DateTime?\n deletedByMemberId String? @db.VarChar(64)\n\n parentTopic Topic? @relation(\"TopicChildren\", fields: [parentTopicId], references: [id])\n childTopics Topic[] @relation(\"TopicChildren\")\n posts Post[]\n ancestorClosures TopicClosure[] @relation(\"TopicClosureAncestor\")\n descendantClosures TopicClosure[] @relation(\"TopicClosureDescendant\")\n watches TopicWatch[]\n readStates TopicReadState[]\n\n @@index([parentTopicId])\n @@index([challengeId])\n @@index([roleName])\n @@index([deletedAt])\n @@index([isAnnouncement, createdAt])\n @@schema(\"forums\")\n}\n\nmodel MemberBan {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n memberId String @db.VarChar(64)\n createdAt DateTime @default(now())\n createdByMemberId String? @db.VarChar(64)\n removedAt DateTime?\n removedByMemberId String? @db.VarChar(64)\n\n @@index([memberId])\n @@index([removedAt])\n @@schema(\"forums\")\n}\n\nmodel IpBan {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n ipAddress String @db.VarChar(45)\n createdAt DateTime @default(now())\n createdByMemberId String? @db.VarChar(64)\n removedAt DateTime?\n removedByMemberId String? @db.VarChar(64)\n\n @@index([ipAddress])\n @@index([removedAt])\n @@schema(\"forums\")\n}\n\nmodel Post {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n topicId String @db.VarChar(14)\n parentType String @db.VarChar(16)\n parentId String @db.VarChar(14)\n authorMemberId String @db.VarChar(64)\n authorHandle String @db.VarChar(128)\n content String? @db.Text\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n deletedAt DateTime?\n deletedByMemberId String? @db.VarChar(64)\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n reactions PostReaction[]\n\n @@index([topicId, createdAt])\n @@index([topicId, parentType, parentId])\n @@index([deletedAt])\n @@schema(\"forums\")\n}\n\nmodel PostReaction {\n postId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n reaction PostReactionType\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n\n post Post @relation(fields: [postId], references: [id], onDelete: Cascade)\n\n @@id([postId, memberId])\n @@index([memberId])\n @@index([postId, reaction])\n @@schema(\"forums\")\n}\n\nmodel TopicClosure {\n ancestorTopicId String @db.VarChar(14)\n descendantTopicId String @db.VarChar(14)\n depth Int\n\n ancestorTopic Topic @relation(\"TopicClosureAncestor\", fields: [ancestorTopicId], references: [id], onDelete: Cascade)\n descendantTopic Topic @relation(\"TopicClosureDescendant\", fields: [descendantTopicId], references: [id], onDelete: Cascade)\n\n @@id([ancestorTopicId, descendantTopicId])\n @@index([ancestorTopicId, depth])\n @@index([descendantTopicId, depth])\n @@schema(\"forums\")\n}\n\nmodel TopicWatch {\n topicId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n createdAt DateTime @default(now())\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@id([topicId, memberId])\n @@index([memberId])\n @@schema(\"forums\")\n}\n\nmodel TopicReadState {\n topicId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n lastReadAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@id([topicId, memberId])\n @@index([memberId])\n @@index([lastReadAt])\n @@schema(\"forums\")\n}\n" } -config.runtimeDataModel = JSON.parse("{\"models\":{\"Topic\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengeId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roleName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isAnnouncement\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"locked\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"lockedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"lockedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorHandle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicChildren\"},{\"name\":\"childTopics\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicChildren\"},{\"name\":\"posts\",\"kind\":\"object\",\"type\":\"Post\",\"relationName\":\"PostToTopic\"},{\"name\":\"ancestorClosures\",\"kind\":\"object\",\"type\":\"TopicClosure\",\"relationName\":\"TopicClosureAncestor\"},{\"name\":\"descendantClosures\",\"kind\":\"object\",\"type\":\"TopicClosure\",\"relationName\":\"TopicClosureDescendant\"},{\"name\":\"watches\",\"kind\":\"object\",\"type\":\"TopicWatch\",\"relationName\":\"TopicToTopicWatch\"},{\"name\":\"readStates\",\"kind\":\"object\",\"type\":\"TopicReadState\",\"relationName\":\"TopicToTopicReadState\"}],\"dbName\":null},\"MemberBan\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"removedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"removedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"IpBan\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"ipAddress\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"removedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"removedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"Post\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorHandle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"PostToTopic\"}],\"dbName\":null},\"TopicClosure\":{\"fields\":[{\"name\":\"ancestorTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"descendantTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"depth\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"ancestorTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicClosureAncestor\"},{\"name\":\"descendantTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicClosureDescendant\"}],\"dbName\":null},\"TopicWatch\":{\"fields\":[{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicToTopicWatch\"}],\"dbName\":null},\"TopicReadState\":{\"fields\":[{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"lastReadAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicToTopicReadState\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"Topic\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengeId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roleName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isAnnouncement\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"locked\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"lockedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"lockedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorHandle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicChildren\"},{\"name\":\"childTopics\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicChildren\"},{\"name\":\"posts\",\"kind\":\"object\",\"type\":\"Post\",\"relationName\":\"PostToTopic\"},{\"name\":\"ancestorClosures\",\"kind\":\"object\",\"type\":\"TopicClosure\",\"relationName\":\"TopicClosureAncestor\"},{\"name\":\"descendantClosures\",\"kind\":\"object\",\"type\":\"TopicClosure\",\"relationName\":\"TopicClosureDescendant\"},{\"name\":\"watches\",\"kind\":\"object\",\"type\":\"TopicWatch\",\"relationName\":\"TopicToTopicWatch\"},{\"name\":\"readStates\",\"kind\":\"object\",\"type\":\"TopicReadState\",\"relationName\":\"TopicToTopicReadState\"}],\"dbName\":null},\"MemberBan\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"removedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"removedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"IpBan\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"ipAddress\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"removedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"removedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"Post\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorHandle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"PostToTopic\"},{\"name\":\"reactions\",\"kind\":\"object\",\"type\":\"PostReaction\",\"relationName\":\"PostToPostReaction\"}],\"dbName\":null},\"PostReaction\":{\"fields\":[{\"name\":\"postId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"reaction\",\"kind\":\"enum\",\"type\":\"PostReactionType\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"post\",\"kind\":\"object\",\"type\":\"Post\",\"relationName\":\"PostToPostReaction\"}],\"dbName\":null},\"TopicClosure\":{\"fields\":[{\"name\":\"ancestorTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"descendantTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"depth\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"ancestorTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicClosureAncestor\"},{\"name\":\"descendantTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicClosureDescendant\"}],\"dbName\":null},\"TopicWatch\":{\"fields\":[{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicToTopicWatch\"}],\"dbName\":null},\"TopicReadState\":{\"fields\":[{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"lastReadAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicToTopicReadState\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") defineDmmfProperty(exports.Prisma, config.runtimeDataModel) config.parameterizationSchema = { - strings: JSON.parse("[\"where\",\"parentTopic\",\"orderBy\",\"cursor\",\"childTopics\",\"topic\",\"posts\",\"ancestorTopic\",\"descendantTopic\",\"ancestorClosures\",\"descendantClosures\",\"watches\",\"readStates\",\"_count\",\"Topic.findUnique\",\"Topic.findUniqueOrThrow\",\"Topic.findFirst\",\"Topic.findFirstOrThrow\",\"Topic.findMany\",\"data\",\"Topic.createOne\",\"Topic.createMany\",\"Topic.createManyAndReturn\",\"Topic.updateOne\",\"Topic.updateMany\",\"Topic.updateManyAndReturn\",\"create\",\"update\",\"Topic.upsertOne\",\"Topic.deleteOne\",\"Topic.deleteMany\",\"having\",\"_min\",\"_max\",\"Topic.groupBy\",\"Topic.aggregate\",\"MemberBan.findUnique\",\"MemberBan.findUniqueOrThrow\",\"MemberBan.findFirst\",\"MemberBan.findFirstOrThrow\",\"MemberBan.findMany\",\"MemberBan.createOne\",\"MemberBan.createMany\",\"MemberBan.createManyAndReturn\",\"MemberBan.updateOne\",\"MemberBan.updateMany\",\"MemberBan.updateManyAndReturn\",\"MemberBan.upsertOne\",\"MemberBan.deleteOne\",\"MemberBan.deleteMany\",\"MemberBan.groupBy\",\"MemberBan.aggregate\",\"IpBan.findUnique\",\"IpBan.findUniqueOrThrow\",\"IpBan.findFirst\",\"IpBan.findFirstOrThrow\",\"IpBan.findMany\",\"IpBan.createOne\",\"IpBan.createMany\",\"IpBan.createManyAndReturn\",\"IpBan.updateOne\",\"IpBan.updateMany\",\"IpBan.updateManyAndReturn\",\"IpBan.upsertOne\",\"IpBan.deleteOne\",\"IpBan.deleteMany\",\"IpBan.groupBy\",\"IpBan.aggregate\",\"Post.findUnique\",\"Post.findUniqueOrThrow\",\"Post.findFirst\",\"Post.findFirstOrThrow\",\"Post.findMany\",\"Post.createOne\",\"Post.createMany\",\"Post.createManyAndReturn\",\"Post.updateOne\",\"Post.updateMany\",\"Post.updateManyAndReturn\",\"Post.upsertOne\",\"Post.deleteOne\",\"Post.deleteMany\",\"Post.groupBy\",\"Post.aggregate\",\"TopicClosure.findUnique\",\"TopicClosure.findUniqueOrThrow\",\"TopicClosure.findFirst\",\"TopicClosure.findFirstOrThrow\",\"TopicClosure.findMany\",\"TopicClosure.createOne\",\"TopicClosure.createMany\",\"TopicClosure.createManyAndReturn\",\"TopicClosure.updateOne\",\"TopicClosure.updateMany\",\"TopicClosure.updateManyAndReturn\",\"TopicClosure.upsertOne\",\"TopicClosure.deleteOne\",\"TopicClosure.deleteMany\",\"_avg\",\"_sum\",\"TopicClosure.groupBy\",\"TopicClosure.aggregate\",\"TopicWatch.findUnique\",\"TopicWatch.findUniqueOrThrow\",\"TopicWatch.findFirst\",\"TopicWatch.findFirstOrThrow\",\"TopicWatch.findMany\",\"TopicWatch.createOne\",\"TopicWatch.createMany\",\"TopicWatch.createManyAndReturn\",\"TopicWatch.updateOne\",\"TopicWatch.updateMany\",\"TopicWatch.updateManyAndReturn\",\"TopicWatch.upsertOne\",\"TopicWatch.deleteOne\",\"TopicWatch.deleteMany\",\"TopicWatch.groupBy\",\"TopicWatch.aggregate\",\"TopicReadState.findUnique\",\"TopicReadState.findUniqueOrThrow\",\"TopicReadState.findFirst\",\"TopicReadState.findFirstOrThrow\",\"TopicReadState.findMany\",\"TopicReadState.createOne\",\"TopicReadState.createMany\",\"TopicReadState.createManyAndReturn\",\"TopicReadState.updateOne\",\"TopicReadState.updateMany\",\"TopicReadState.updateManyAndReturn\",\"TopicReadState.upsertOne\",\"TopicReadState.deleteOne\",\"TopicReadState.deleteMany\",\"TopicReadState.groupBy\",\"TopicReadState.aggregate\",\"AND\",\"OR\",\"NOT\",\"topicId\",\"memberId\",\"lastReadAt\",\"updatedAt\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"not\",\"contains\",\"startsWith\",\"endsWith\",\"createdAt\",\"ancestorTopicId\",\"descendantTopicId\",\"depth\",\"id\",\"parentType\",\"parentId\",\"authorMemberId\",\"authorHandle\",\"content\",\"deletedAt\",\"deletedByMemberId\",\"ipAddress\",\"createdByMemberId\",\"removedAt\",\"removedByMemberId\",\"parentTopicId\",\"challengeId\",\"roleName\",\"title\",\"isAnnouncement\",\"locked\",\"lockedAt\",\"lockedByMemberId\",\"topicId_memberId\",\"ancestorTopicId_descendantTopicId\",\"every\",\"some\",\"none\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"), - graph: "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_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_AEAIIkBAQAAAAGKAQEAAAABmAFAAAAAAQETAACYAQAgA4kBAQAAAAGKAQEAAAABmAFAAAAAAQETAACaAQAwARMAAJoBADAEBQAA-wEAIIkBAQD0AQAhigEBAPQBACGYAUAA9QEAIQIAAAASACATAACdAQAgA4kBAQD0AQAhigEBAPQBACGYAUAA9QEAIQIAAAAQACATAACfAQAgAgAAABAAIBMAAJ8BACADAAAAEgAgGgAAmAEAIBsAAJ0BACABAAAAEgAgAQAAABAAIAMNAAD4AQAgIAAA-gEAICEAAPkBACAGhgEAAMcBADCHAQAApgEAEIgBAADHAQAwiQEBAMABACGKAQEAwAEAIZgBQADBAQAhAwAAABAAIAIAAKUBADAfAACmAQAgAwAAABAAIAIAABEAMAMAABIAIAEAAAAWACABAAAAFgAgAwAAABQAIAIAABUAMAMAABYAIAMAAAAUACACAAAVADADAAAWACADAAAAFAAgAgAAFQAwAwAAFgAgBQUAAPcBACCJAQEAAAABigEBAAAAAYsBQAAAAAGMAUAAAAABARMAAK4BACAEiQEBAAAAAYoBAQAAAAGLAUAAAAABjAFAAAAAAQETAACwAQAwARMAALABADAFBQAA9gEAIIkBAQD0AQAhigEBAPQBACGLAUAA9QEAIYwBQAD1AQAhAgAAABYAIBMAALMBACAEiQEBAPQBACGKAQEA9AEAIYsBQAD1AQAhjAFAAPUBACECAAAAFAAgEwAAtQEAIAIAAAAUACATAAC1AQAgAwAAABYAIBoAAK4BACAbAACzAQAgAQAAABYAIAEAAAAUACADDQAA8QEAICAAAPMBACAhAADyAQAgB4YBAAC_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_wIAIL0BAAABACADGgAA_QIAILcBAAD-AgAgvQEAAAEAIAAAAAAAAAAAAAG6ASAAAAABBxoAAPICACAbAAD7AgAgtwEAAPMCACC4AQAA-gIAILsBAAADACC8AQAAAwAgvQEAAAEAIAsaAADZAgAwGwAA3gIAMLcBAADaAgAwuAEAANsCADC5AQAA3AIAILoBAADdAgAwuwEAAN0CADC8AQAA3QIAML0BAADdAgAwvgEAAN8CADC_AQAA4AIAMAsaAADNAgAwGwAA0gIAMLcBAADOAgAwuAEAAM8CADC5AQAA0AIAILoBAADRAgAwuwEAANECADC8AQAA0QIAML0BAADRAgAwvgEAANMCADC_AQAA1AIAMAsaAADEAgAwGwAAyAIAMLcBAADFAgAwuAEAAMYCADC5AQAAxwIAILoBAAC8AgAwuwEAALwCADC8AQAAvAIAML0BAAC8AgAwvgEAAMkCADC_AQAAvwIAMAsaAAC4AgAwGwAAvQIAMLcBAAC5AgAwuAEAALoCADC5AQAAuwIAILoBAAC8AgAwuwEAALwCADC8AQAAvAIAML0BAAC8AgAwvgEAAL4CADC_AQAAvwIAMAsaAACsAgAwGwAAsQIAMLcBAACtAgAwuAEAAK4CADC5AQAArwIAILoBAACwAgAwuwEAALACADC8AQAAsAIAML0BAACwAgAwvgEAALICADC_AQAAswIAMAsaAACgAgAwGwAApQIAMLcBAAChAgAwuAEAAKICADC5AQAAowIAILoBAACkAgAwuwEAAKQCADC8AQAApAIAML0BAACkAgAwvgEAAKYCADC_AQAApwIAMAOKAQEAAAABiwFAAAAAAYwBQAAAAAECAAAAFgAgGgAAqwIAIAMAAAAWACAaAACrAgAgGwAAqgIAIAETAAD5AgAwCQUAAOIBACCGAQAA4QEAMIcBAAAUABCIAQAA4QEAMIkBAQDWAQAhigEBANYBACGLAUAA1wEAIYwBQADXAQAhsAEAAOABACACAAAAFgAgEwAAqgIAIAIAAACoAgAgEwAAqQIAIAeGAQAApwIAMIcBAACoAgAQiAEAAKcCADCJAQEA1gEAIYoBAQDWAQAhiwFAANcBACGMAUAA1wEAIQeGAQAApwIAMIcBAACoAgAQiAEAAKcCADCJAQEA1gEAIYoBAQDWAQAhiwFAANcBACGMAUAA1wEAIQOKAQEA9AEAIYsBQAD1AQAhjAFAAPUBACEDigEBAPQBACGLAUAA9QEAIYwBQAD1AQAhA4oBAQAAAAGLAUAAAAABjAFAAAAAAQKKAQEAAAABmAFAAAAAAQIAAAASACAaAAC3AgAgAwAAABIAIBoAALcCACAbAAC2AgAgARMAAPgCADAIBQAA4gEAIIYBAADkAQAwhwEAABAAEIgBAADkAQAwiQEBANYBACGKAQEA1gEAIZgBQADXAQAhsAEAAOMBACACAAAAEgAgEwAAtgIAIAIAAAC0AgAgEwAAtQIAIAaGAQAAswIAMIcBAAC0AgAQiAEAALMCADCJAQEA1gEAIYoBAQDWAQAhmAFAANcBACEGhgEAALMCADCHAQAAtAIAEIgBAACzAgAwiQEBANYBACGKAQEA1gEAIZgBQADXAQAhAooBAQD0AQAhmAFAAPUBACECigEBAPQBACGYAUAA9QEAIQKKAQEAAAABmAFAAAAAAQMHAACFAgAgmQEBAAAAAZsBAgAAAAECAAAADQAgGgAAwwIAIAMAAAANACAaAADDAgAgGwAAwgIAIAETAAD3AgAwCQcAAOIBACAIAADiAQAghgEAAOYBADCHAQAACwAQiAEAAOYBADCZAQEA1gEAIZoBAQDWAQAhmwECAOcBACGxAQAA5QEAIAIAAAANACATAADCAgAgAgAAAMACACATAADBAgAgBoYBAAC_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_AIAIIwBQAD1AQAhmAFAAPUBACGcAQEA9AEAIZ8BAQD0AQAhoAEBAPQBACGiAUAAjAIAIaMBAQCLAgAhqAEBAIsCACGpAQEAiwIAIaoBAQCLAgAhqwEBAPQBACGsASAAmAIAIa0BIACYAgAhrgFAAIwCACGvAQEAiwIAIRUBAACZAgAgBgAAmwIAIAkAAJwCACAKAACdAgAgCwAAngIAIAwAAJ8CACCMAUAA9QEAIZgBQAD1AQAhnAEBAPQBACGfAQEA9AEAIaABAQD0AQAhogFAAIwCACGjAQEAiwIAIagBAQCLAgAhqQEBAIsCACGqAQEAiwIAIasBAQD0AQAhrAEgAJgCACGtASAAmAIAIa4BQACMAgAhrwEBAIsCACEVAQAA6wIAIAQAAOUCACAJAADnAgAgCgAA6AIAIAsAAOkCACAMAADqAgAgjAFAAAAAAZgBQAAAAAGcAQEAAAABnwEBAAAAAaABAQAAAAGiAUAAAAABowEBAAAAAagBAQAAAAGpAQEAAAABqgEBAAAAAasBAQAAAAGsASAAAAABrQEgAAAAAa4BQAAAAAGvAQEAAAABAgAAAAEAIBoAAP0CACADAAAAAwAgGgAA_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-Xxk_YBdAYRdBYgdCZRpDZh5EZwJFaAJGaQJHagJIawJJbQJKbwdLcB9McgJNdAdOdSBPdgJQdwJReAdSeyFTfCVUfQNVfgNWfwNXgAEDWIEBA1mDAQNahQEHW4YBJlyIAQNdigEHXosBJ1-MAQNgjQEDYY4BB2SRAShlkgEuZpMBBGeUAQRolQEEaZYBBGqXAQRrmQEEbJsBB22cAS9ungEEb6ABB3ChATBxogEEcqMBBHOkAQd0pwExdagBNXapAQV3qgEFeKsBBXmsAQV6rQEFe68BBXyxAQd9sgE2frQBBX-2AQeAAbcBN4EBuAEFggG5AQWDAboBB4QBvQE4hQG-ATw" + strings: JSON.parse("[\"where\",\"parentTopic\",\"orderBy\",\"cursor\",\"childTopics\",\"topic\",\"post\",\"reactions\",\"_count\",\"posts\",\"ancestorTopic\",\"descendantTopic\",\"ancestorClosures\",\"descendantClosures\",\"watches\",\"readStates\",\"Topic.findUnique\",\"Topic.findUniqueOrThrow\",\"Topic.findFirst\",\"Topic.findFirstOrThrow\",\"Topic.findMany\",\"data\",\"Topic.createOne\",\"Topic.createMany\",\"Topic.createManyAndReturn\",\"Topic.updateOne\",\"Topic.updateMany\",\"Topic.updateManyAndReturn\",\"create\",\"update\",\"Topic.upsertOne\",\"Topic.deleteOne\",\"Topic.deleteMany\",\"having\",\"_min\",\"_max\",\"Topic.groupBy\",\"Topic.aggregate\",\"MemberBan.findUnique\",\"MemberBan.findUniqueOrThrow\",\"MemberBan.findFirst\",\"MemberBan.findFirstOrThrow\",\"MemberBan.findMany\",\"MemberBan.createOne\",\"MemberBan.createMany\",\"MemberBan.createManyAndReturn\",\"MemberBan.updateOne\",\"MemberBan.updateMany\",\"MemberBan.updateManyAndReturn\",\"MemberBan.upsertOne\",\"MemberBan.deleteOne\",\"MemberBan.deleteMany\",\"MemberBan.groupBy\",\"MemberBan.aggregate\",\"IpBan.findUnique\",\"IpBan.findUniqueOrThrow\",\"IpBan.findFirst\",\"IpBan.findFirstOrThrow\",\"IpBan.findMany\",\"IpBan.createOne\",\"IpBan.createMany\",\"IpBan.createManyAndReturn\",\"IpBan.updateOne\",\"IpBan.updateMany\",\"IpBan.updateManyAndReturn\",\"IpBan.upsertOne\",\"IpBan.deleteOne\",\"IpBan.deleteMany\",\"IpBan.groupBy\",\"IpBan.aggregate\",\"Post.findUnique\",\"Post.findUniqueOrThrow\",\"Post.findFirst\",\"Post.findFirstOrThrow\",\"Post.findMany\",\"Post.createOne\",\"Post.createMany\",\"Post.createManyAndReturn\",\"Post.updateOne\",\"Post.updateMany\",\"Post.updateManyAndReturn\",\"Post.upsertOne\",\"Post.deleteOne\",\"Post.deleteMany\",\"Post.groupBy\",\"Post.aggregate\",\"PostReaction.findUnique\",\"PostReaction.findUniqueOrThrow\",\"PostReaction.findFirst\",\"PostReaction.findFirstOrThrow\",\"PostReaction.findMany\",\"PostReaction.createOne\",\"PostReaction.createMany\",\"PostReaction.createManyAndReturn\",\"PostReaction.updateOne\",\"PostReaction.updateMany\",\"PostReaction.updateManyAndReturn\",\"PostReaction.upsertOne\",\"PostReaction.deleteOne\",\"PostReaction.deleteMany\",\"PostReaction.groupBy\",\"PostReaction.aggregate\",\"TopicClosure.findUnique\",\"TopicClosure.findUniqueOrThrow\",\"TopicClosure.findFirst\",\"TopicClosure.findFirstOrThrow\",\"TopicClosure.findMany\",\"TopicClosure.createOne\",\"TopicClosure.createMany\",\"TopicClosure.createManyAndReturn\",\"TopicClosure.updateOne\",\"TopicClosure.updateMany\",\"TopicClosure.updateManyAndReturn\",\"TopicClosure.upsertOne\",\"TopicClosure.deleteOne\",\"TopicClosure.deleteMany\",\"_avg\",\"_sum\",\"TopicClosure.groupBy\",\"TopicClosure.aggregate\",\"TopicWatch.findUnique\",\"TopicWatch.findUniqueOrThrow\",\"TopicWatch.findFirst\",\"TopicWatch.findFirstOrThrow\",\"TopicWatch.findMany\",\"TopicWatch.createOne\",\"TopicWatch.createMany\",\"TopicWatch.createManyAndReturn\",\"TopicWatch.updateOne\",\"TopicWatch.updateMany\",\"TopicWatch.updateManyAndReturn\",\"TopicWatch.upsertOne\",\"TopicWatch.deleteOne\",\"TopicWatch.deleteMany\",\"TopicWatch.groupBy\",\"TopicWatch.aggregate\",\"TopicReadState.findUnique\",\"TopicReadState.findUniqueOrThrow\",\"TopicReadState.findFirst\",\"TopicReadState.findFirstOrThrow\",\"TopicReadState.findMany\",\"TopicReadState.createOne\",\"TopicReadState.createMany\",\"TopicReadState.createManyAndReturn\",\"TopicReadState.updateOne\",\"TopicReadState.updateMany\",\"TopicReadState.updateManyAndReturn\",\"TopicReadState.upsertOne\",\"TopicReadState.deleteOne\",\"TopicReadState.deleteMany\",\"TopicReadState.groupBy\",\"TopicReadState.aggregate\",\"AND\",\"OR\",\"NOT\",\"topicId\",\"memberId\",\"lastReadAt\",\"updatedAt\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"not\",\"contains\",\"startsWith\",\"endsWith\",\"createdAt\",\"ancestorTopicId\",\"descendantTopicId\",\"depth\",\"postId\",\"PostReactionType\",\"reaction\",\"id\",\"parentType\",\"parentId\",\"authorMemberId\",\"authorHandle\",\"content\",\"deletedAt\",\"deletedByMemberId\",\"ipAddress\",\"createdByMemberId\",\"removedAt\",\"removedByMemberId\",\"parentTopicId\",\"challengeId\",\"roleName\",\"title\",\"isAnnouncement\",\"locked\",\"lockedAt\",\"lockedByMemberId\",\"topicId_memberId\",\"ancestorTopicId_descendantTopicId\",\"postId_memberId\",\"every\",\"some\",\"none\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"), + graph: "1QNFgAEZAQAAjwIAIAQAAJACACAJAACRAgAgDAAAkgIAIA0AAJICACAOAACTAgAgDwAAlAIAIJgBAACNAgAwmQEAAAMAEJoBAACNAgAwngFAAPYBACGqAUAA9gEAIbEBAQAAAAG0AQEA9QEAIbUBAQD1AQAhtwFAAPgBACG4AQEA9wEAIb0BAQD3AQAhvgEBAPcBACG_AQEA9wEAIcABAQD1AQAhwQEgAI4CACHCASAAjgIAIcMBQAD4AQAhxAEBAPcBACEBAAAAAQAgGQEAAI8CACAEAACQAgAgCQAAkQIAIAwAAJICACANAACSAgAgDgAAkwIAIA8AAJQCACCYAQAAjQIAMJkBAAADABCaAQAAjQIAMJ4BQAD2AQAhqgFAAPYBACGxAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG3AUAA-AEAIbgBAQD3AQAhvQEBAPcBACG-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_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_ABCaAQAA6wEAMJsBAQDbAQAhngFAANwBACGqAUAA3AEAIbEBAQDbAQAhsgEBANsBACGzAQEA2wEAIbQBAQDbAQAhtQEBANsBACG2AQEA7AEAIbcBQADtAQAhuAEBAOwBACEDAAAABwAgAgAAfgAwIQAAfwAgAwAAAAcAIAIAAAgAMAMAAAkAIAEAAAANACABAAAADQAgAwAAAAsAIAIAAAwAMAMAAA0AIAMAAAALACACAAAMADADAAANACADAAAACwAgAgAADAAwAwAADQAgBgYAALACACCcAQEAAAABngFAAAAAAaoBQAAAAAGuAQEAAAABsAEAAACwAQIBFQAAhwEAIAWcAQEAAAABngFAAAAAAaoBQAAAAAGuAQEAAAABsAEAAACwAQIBFQAAiQEAMAEVAACJAQAwBgYAAK8CACCcAQEAmAIAIZ4BQACZAgAhqgFAAJkCACGuAQEAmAIAIbABAACuArABIgIAAAANACAVAACMAQAgBZwBAQCYAgAhngFAAJkCACGqAUAAmQIAIa4BAQCYAgAhsAEAAK4CsAEiAgAAAAsAIBUAAI4BACACAAAACwAgFQAAjgEAIAMAAAANACAcAACHAQAgHQAAjAEAIAEAAAANACABAAAACwAgAwgAAKsCACAiAACtAgAgIwAArAIAIAiYAQAA5wEAMJkBAACVAQAQmgEAAOcBADCcAQEA2wEAIZ4BQADcAQAhqgFAANwBACGuAQEA2wEAIbABAADoAbABIgMAAAALACACAACUAQAwIQAAlQEAIAMAAAALACACAAAMADADAAANACABAAAAEgAgAQAAABIAIAMAAAAQACACAAARADADAAASACADAAAAEAAgAgAAEQAwAwAAEgAgAwAAABAAIAIAABEAMAMAABIAIAUKAACpAgAgCwAAqgIAIKsBAQAAAAGsAQEAAAABrQECAAAAAQEVAACdAQAgA6sBAQAAAAGsAQEAAAABrQECAAAAAQEVAACfAQAwARUAAJ8BADAFCgAApwIAIAsAAKgCACCrAQEAmAIAIawBAQCYAgAhrQECAKYCACECAAAAEgAgFQAAogEAIAOrAQEAmAIAIawBAQCYAgAhrQECAKYCACECAAAAEAAgFQAApAEAIAIAAAAQACAVAACkAQAgAwAAABIAIBwAAJ0BACAdAACiAQAgAQAAABIAIAEAAAAQ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AAABoAEBAAAABaEBAQAAAAWiAQEAAAABowEBAAAAAaQBAQAAAAGlAQEAAAABpgEBAPIBACGnAQEAAAABqAEBAAAAAakBAQAAAAEJmAEAAPMBADCZAQAAaQAQmgEAAPMBADCqAUAA3AEAIbEBAQDbAQAhuQEBANsBACG6AQEA7AEAIbsBQADtAQAhvAEBAOwBACEJmAEAAPQBADCZAQAAVgAQmgEAAPQBADCqAUAA9gEAIbEBAQD1AQAhuQEBAPUBACG6AQEA9wEAIbsBQAD4AQAhvAEBAPcBACELnwEBAAAAAaABAQAAAAShAQEAAAAEogEBAAAAAaMBAQAAAAGkAQEAAAABpQEBAAAAAaYBAQDhAQAhpwEBAAAAAagBAQAAAAGpAQEAAAABCJ8BQAAAAAGgAUAAAAAEoQFAAAAABKIBQAAAAAGjAUAAAAABpAFAAAAAAaUBQAAAAAGmAUAA3wEAIQufAQEAAAABoAEBAAAABaEBAQAAAAWiAQEAAAABowEBAAAAAaQBAQAAAAGlAQEAAAABpgEBAPIBACGnAQEAAAABqAEBAAAAAakBAQAAAAEInwFAAAAAAaABQAAAAAWhAUAAAAAFogFAAAAAAaMBQAAAAAGkAUAAAAABpQFAAAAAAaYBQADwAQAhCZgBAAD5AQAwmQEAAFAAEJoBAAD5AQAwnAEBANsBACGqAUAA3AEAIbEBAQDbAQAhugEBAOwBACG7AUAA7QEAIbwBAQDsAQAhCZgBAAD6AQAwmQEAAD0AEJoBAAD6AQAwnAEBAPUBACGqAUAA9gEAIbEBAQD1AQAhugEBAPcBACG7AUAA-AEAIbwBAQD3AQAhEpgBAAD7AQAwmQEAADcAEJoBAAD7AQAwngFAANwBACGqAUAA3AEAIbEBAQDbAQAhtAEBANsBACG1AQEA2wEAIbcBQADtAQAhuAEBAOwBACG9AQEA7AEAIb4BAQDsAQAhvwEBAOwBACHAAQEA2wEAIcEBIAD8AQAhwgEgAPwBACHDAUAA7QEAIcQBAQDsAQAhBQgAAN4BACAiAAD-AQAgIwAA_gEAIJ8BIAAAAAGmASAA_QEAIQUIAADeAQAgIgAA_gEAICMAAP4BACCfASAAAAABpgEgAP0BACECnwEgAAAAAaYBIAD-AQAhApsBAQAAAAGcAQEAAAABCAUAAIECACCYAQAAgAIAMJkBAAAZABCaAQAAgAIAMJsBAQD1AQAhnAEBAPUBACGdAUAA9gEAIZ4BQAD2AQAhGwEAAI8CACAEAACQAgAgCQAAkQIAIAwAAJICACANAACSAgAgDgAAkwIAIA8AAJQCACCYAQAAjQIAMJkBAAADABCaAQAAjQIAMJ4BQAD2AQAhqgFAAPYBACGxAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG3AUAA-AEAIbgBAQD3AQAhvQEBAPcBACG-AQEA9wEAIb8BAQD3AQAhwAEBAPUBACHBASAAjgIAIcIBIACOAgAhwwFAAPgBACHEAQEA9wEAIcsBAAADACDMAQAAAwAgApsBAQAAAAGcAQEAAAABBwUAAIECACCYAQAAgwIAMJkBAAAVABCaAQAAgwIAMJsBAQD1AQAhnAEBAPUBACGqAUAA9gEAIQKrAQEAAAABrAEBAAAAAQgKAACBAgAgCwAAgQIAIJgBAACFAgAwmQEAABAAEJoBAACFAgAwqwEBAPUBACGsAQEA9QEAIa0BAgCGAgAhCJ8BAgAAAAGgAQIAAAAEoQECAAAABKIBAgAAAAGjAQIAAAABpAECAAAAAaUBAgAAAAGmAQIA3gEAIQKcAQEAAAABrgEBAAAAAQkGAACKAgAgmAEAAIgCADCZAQAACwAQmgEAAIgCADCcAQEA9QEAIZ4BQAD2AQAhqgFAAPYBACGuAQEA9QEAIbABAACJArABIgSfAQAAALABAqABAAAAsAEIoQEAAACwAQimAQAA6gGwASISBQAAgQIAIAcAAIwCACCYAQAAiwIAMJkBAAAHABCaAQAAiwIAMJsBAQD1AQAhngFAAPYBACGqAUAA9gEAIbEBAQD1AQAhsgEBAPUBACGzAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG2AQEA9wEAIbcBQAD4AQAhuAEBAPcBACHLAQAABwAgzAEAAAcAIBAFAACBAgAgBwAAjAIAIJgBAACLAgAwmQEAAAcAEJoBAACLAgAwmwEBAPUBACGeAUAA9gEAIaoBQAD2AQAhsQEBAPUBACGyAQEA9QEAIbMBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbYBAQD3AQAhtwFAAPgBACG4AQEA9wEAIQPIAQAACwAgyQEAAAsAIMoBAAALACAZAQAAjwIAIAQAAJACACAJAACRAgAgDAAAkgIAIA0AAJICACAOAACTAgAgDwAAlAIAIJgBAACNAgAwmQEAAAMAEJoBAACNAgAwngFAAPYBACGqAUAA9gEAIbEBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbcBQAD4AQAhuAEBAPcBACG9AQEA9wEAIb4BAQD3AQAhvwEBAPcBACHAAQEA9QEAIcEBIACOAgAhwgEgAI4CACHDAUAA-AEAIcQBAQD3AQAhAp8BIAAAAAGmASAA_gEAIRsBAACPAgAgBAAAkAIAIAkAAJECACAMAACSAgAgDQAAkgIAIA4AAJMCACAPAACUAgAgmAEAAI0CADCZAQAAAwAQmgEAAI0CADCeAUAA9gEAIaoBQAD2AQAhsQEBAPUBACG0AQEA9QEAIbUBAQD1AQAhtwFAAPgBACG4AQEA9wEAIb0BAQD3AQAhvgEBAPcBACG_AQEA9wEAIcABAQD1AQAhwQEgAI4CACHCASAAjgIAIcMBQAD4AQAhxAEBAPcBACHLAQAAAwAgzAEAAAMAIAPIAQAAAwAgyQEAAAMAIMoBAAADACADyAEAAAcAIMkBAAAHACDKAQAABwAgA8gBAAAQACDJAQAAEAAgygEAABAAIAPIAQAAFQAgyQEAABUAIMoBAAAVACADyAEAABkAIMkBAAAZACDKAQAAGQAgAAAAAdABAQAAAAEB0AFAAAAAAQUcAADRAwAgHQAA1AMAIM0BAADSAwAgzgEAANMDACDTAQAAAQAgAxwAANEDACDNAQAA0gMAINMBAAABACAAAAAFHAAAzAMAIB0AAM8DACDNAQAAzQMAIM4BAADOAwAg0wEAAAEAIAMcAADMAwAgzQEAAM0DACDTAQAAAQAgAAAAAAAF0AECAAAAAdYBAgAAAAHXAQIAAAAB2AECAAAAAdkBAgAAAAEFHAAAxAMAIB0AAMoDACDNAQAAxQMAIM4BAADJAwAg0wEAAAEAIAUcAADCAwAgHQAAxwMAIM0BAADDAwAgzgEAAMYDACDTAQAAAQAgAxwAAMQDACDNAQAAxQMAINMBAAABACADHAAAwgMAIM0BAADDAwAg0wEAAAEAIAAAAAHQAQAAALABAgUcAAC9AwAgHQAAwAMAIM0BAAC-AwAgzgEAAL8DACDTAQAACQAgAxwAAL0DACDNAQAAvgMAINMBAAAJACAAAAAAAdABAQAAAAEB0AFAAAAAAQUcAAC3AwAgHQAAuwMAIM0BAAC4AwAgzgEAALoDACDTAQAAAQAgCxwAALkCADAdAAC-AgAwzQEAALoCADDOAQAAuwIAMM8BAAC8AgAg0AEAAL0CADDRAQAAvQIAMNIBAAC9AgAw0wEAAL0CADDUAQAAvwIAMNUBAADAAgAwBJwBAQAAAAGeAUAAAAABqgFAAAAAAbABAAAAsAECAgAAAA0AIBwAAMQCACADAAAADQAgHAAAxAIAIB0AAMMCACABFQAAuQMAMAoGAACKAgAgmAEAAIgCADCZAQAACwAQmgEAAIgCADCcAQEA9QEAIZ4BQAD2AQAhqgFAAPYBACGuAQEA9QEAIbABAACJArABIscBAACHAgAgAgAAAA0AIBUAAMMCACACAAAAwQIAIBUAAMICACAImAEAAMACADCZAQAAwQIAEJoBAADAAgAwnAEBAPUBACGeAUAA9gEAIaoBQAD2AQAhrgEBAPUBACGwAQAAiQKwASIImAEAAMACADCZAQAAwQIAEJoBAADAAgAwnAEBAPUBACGeAUAA9gEAIaoBQAD2AQAhrgEBAPUBACGwAQAAiQKwASIEnAEBAJgCACGeAUAAmQIAIaoBQACZAgAhsAEAAK4CsAEiBJwBAQCYAgAhngFAAJkCACGqAUAAmQIAIbABAACuArABIgScAQEAAAABngFAAAAAAaoBQAAAAAGwAQAAALABAgMcAAC3AwAgzQEAALgDACDTAQAAAQAgBBwAALkCADDNAQAAugIAMM8BAAC8AgAg0wEAAL0CADAAAAAAAAAAAAAB0AEgAAAAAQccAACsAwAgHQAAtQMAIM0BAACtAwAgzgEAALQDACDRAQAAAwAg0gEAAAMAINMBAAABACALHAAAkQMAMB0AAJYDADDNAQAAkgMAMM4BAACTAwAwzwEAAJQDACDQAQAAlQMAMNEBAACVAwAw0gEAAJUDADDTAQAAlQMAMNQBAACXAwAw1QEAAJgDADALHAAAhQMAMB0AAIoDADDNAQAAhgMAMM4BAACHAwAwzwEAAIgDACDQAQAAiQMAMNEBAACJAwAw0gEAAIkDADDTAQAAiQMAMNQBAACLAwAw1QEAAIwDADALHAAA_AIAMB0AAIADADDNAQAA_QIAMM4BAAD-AgAwzwEAAP8CACDQAQAA9AIAMNEBAAD0AgAw0gEAAPQCADDTAQAA9AIAMNQBAACBAwAw1QEAAPcCADALHAAA8AIAMB0AAPUCADDNAQAA8QIAMM4BAADyAgAwzwEAAPMCACDQAQAA9AIAMNEBAAD0AgAw0gEAAPQCADDTAQAA9AIAMNQBAAD2AgAw1QEAAPcCADALHAAA5AIAMB0AAOkCADDNAQAA5QIAMM4BAADmAgAwzwEAAOcCACDQAQAA6AIAMNEBAADoAgAw0gEAAOgCADDTAQAA6AIAMNQBAADqAgAw1QEAAOsCADALHAAA2AIAMB0AAN0CADDNAQAA2QIAMM4BAADaAgAwzwEAANsCACDQAQAA3AIAMNEBAADcAgAw0gEAANwCADDTAQAA3AIAMNQBAADeAgAw1QEAAN8CADADnAEBAAAAAZ0BQAAAAAGeAUAAAAABAgAAABsAIBwAAOMCACADAAAAGwAgHAAA4wIAIB0AAOICACABFQAAswMAMAkFAACBAgAgmAEAAIACADCZAQAAGQAQmgEAAIACADCbAQEA9QEAIZwBAQD1AQAhnQFAAPYBACGeAUAA9gEAIcUBAAD_AQAgAgAAABsAIBUAAOICACACAAAA4AIAIBUAAOECACAHmAEAAN8CADCZAQAA4AIAEJoBAADfAgAwmwEBAPUBACGcAQEA9QEAIZ0BQAD2AQAhngFAAPYBACEHmAEAAN8CADCZAQAA4AIAEJoBAADfAgAwmwEBAPUBACGcAQEA9QEAIZ0BQAD2AQAhngFAAPYBACEDnAEBAJgCACGdAUAAmQIAIZ4BQACZAgAhA5wBAQCYAgAhnQFAAJkCACGeAUAAmQIAIQOcAQEAAAABnQFAAAAAAZ4BQAAAAAECnAEBAAAAAaoBQAAAAAECAAAAFwAgHAAA7wIAIAMAAAAXACAcAADvAgAgHQAA7gIAIAEVAACyAwAwCAUAAIECACCYAQAAgwIAMJkBAAAVABCaAQAAgwIAMJsBAQD1AQAhnAEBAPUBACGqAUAA9gEAIcUBAACCAgAgAgAAABcAIBUAAO4CACACAAAA7AIAIBUAAO0CACAGmAEAAOsCADCZAQAA7AIAEJoBAADrAgAwmwEBAPUBACGcAQEA9QEAIaoBQAD2AQAhBpgBAADrAgAwmQEAAOwCABCaAQAA6wIAMJsBAQD1AQAhnAEBAPUBACGqAUAA9gEAIQKcAQEAmAIAIaoBQACZAgAhApwBAQCYAgAhqgFAAJkCACECnAEBAAAAAaoBQAAAAAEDCgAAqQIAIKsBAQAAAAGtAQIAAAABAgAAABIAIBwAAPsCACADAAAAEgAgHAAA-wIAIB0AAPoCACABFQAAsQMAMAkKAACBAgAgCwAAgQIAIJgBAACFAgAwmQEAABAAEJoBAACFAgAwqwEBAPUBACGsAQEA9QEAIa0BAgCGAgAhxgEAAIQCACACAAAAEgAgFQAA-gIAIAIAAAD4AgAgFQAA-QIAIAaYAQAA9wIAMJkBAAD4AgAQmgEAAPcCADCrAQEA9QEAIawBAQD1AQAhrQECAIYCACEGmAEAAPcCADCZAQAA-AIAEJoBAAD3AgAwqwEBAPUBACGsAQEA9QEAIa0BAgCGAgAhAqsBAQCYAgAhrQECAKYCACEDCgAApwIAIKsBAQCYAgAhrQECAKYCACEDCgAAqQIAIKsBAQAAAAGtAQIAAAABAwsAAKoCACCsAQEAAAABrQECAAAAAQIAAAASACAcAACEAwAgAwAAABIAIBwAAIQDACAdAACDAwAgARUAALADADACAAAAEgAgFQAAgwMAIAIAAAD4AgAgFQAAggMAIAKsAQEAmAIAIa0BAgCmAgAhAwsAAKgCACCsAQEAmAIAIa0BAgCmAgAhAwsAAKoCACCsAQEAAAABrQECAAAAAQsHAADGAgAgngFAAAAAAaoBQAAAAAGxAQEAAAABsgEBAAAAAbMBAQAAAAG0AQEAAAABtQEBAAAAAbYBAQAAAAG3AUAAAAABuAEBAAAAAQIAAAAJACAcAACQAwAgAwAAAAkAIBwAAJADACAdAACPAwAgARUAAK8DADAQBQAAgQIAIAcAAIwCACCYAQAAiwIAMJkBAAAHABCaAQAAiwIAMJsBAQD1AQAhngFAAPYBACGqAUAA9gEAIbEBAQAAAAGyAQEA9QEAIbMBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbYBAQD3AQAhtwFAAPgBACG4AQEA9wEAIQIAAAAJACAVAACPAwAgAgAAAI0DACAVAACOAwAgDpgBAACMAwAwmQEAAI0DABCaAQAAjAMAMJsBAQD1AQAhngFAAPYBACGqAUAA9gEAIbEBAQD1AQAhsgEBAPUBACGzAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG2AQEA9wEAIbcBQAD4AQAhuAEBAPcBACEOmAEAAIwDADCZAQAAjQMAEJoBAACMAwAwmwEBAPUBACGeAUAA9gEAIaoBQAD2AQAhsQEBAPUBACGyAQEA9QEAIbMBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbYBAQD3AQAhtwFAAPgBACG4AQEA9wEAIQqeAUAAmQIAIaoBQACZAgAhsQEBAJgCACGyAQEAmAIAIbMBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbYBAQC1AgAhtwFAALYCACG4AQEAtQIAIQsHAAC4AgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhsgEBAJgCACGzAQEAmAIAIbQBAQCYAgAhtQEBAJgCACG2AQEAtQIAIbcBQAC2AgAhuAEBALUCACELBwAAxgIAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbIBAQAAAAGzAQEAAAABtAEBAAAAAbUBAQAAAAG2AQEAAAABtwFAAAAAAbgBAQAAAAEUBAAAnQMAIAkAAJ4DACAMAACfAwAgDQAAoAMAIA4AAKEDACAPAACiAwAgngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAAAAAcEBIAAAAAHCASAAAAABwwFAAAAAAcQBAQAAAAECAAAAAQAgHAAAnAMAIAMAAAABACAcAACcAwAgHQAAmwMAIAEVAACuAwAwGQEAAI8CACAEAACQAgAgCQAAkQIAIAwAAJICACANAACSAgAgDgAAkwIAIA8AAJQCACCYAQAAjQIAMJkBAAADABCaAQAAjQIAMJ4BQAD2AQAhqgFAAPYBACGxAQEAAAABtAEBAPUBACG1AQEA9QEAIbcBQAD4AQAhuAEBAPcBACG9AQEA9wEAIb4BAQD3AQAhvwEBAPcBACHAAQEA9QEAIcEBIACOAgAhwgEgAI4CACHDAUAA-AEAIcQBAQD3AQAhAgAAAAEAIBUAAJsDACACAAAAmQMAIBUAAJoDACASmAEAAJgDADCZAQAAmQMAEJoBAACYAwAwngFAAPYBACGqAUAA9gEAIbEBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbcBQAD4AQAhuAEBAPcBACG9AQEA9wEAIb4BAQD3AQAhvwEBAPcBACHAAQEA9QEAIcEBIACOAgAhwgEgAI4CACHDAUAA-AEAIcQBAQD3AQAhEpgBAACYAwAwmQEAAJkDABCaAQAAmAMAMJ4BQAD2AQAhqgFAAPYBACGxAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG3AUAA-AEAIbgBAQD3AQAhvQEBAPcBACG-AQEA9wEAIb8BAQD3AQAhwAEBAPUBACHBASAAjgIAIcIBIACOAgAhwwFAAPgBACHEAQEA9wEAIQ6eAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhFAQAANICACAJAADTAgAgDAAA1AIAIA0AANUCACAOAADWAgAgDwAA1wIAIJ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbQBAQCYAgAhtQEBAJgCACG3AUAAtgIAIbgBAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEUBAAAnQMAIAkAAJ4DACAMAACfAwAgDQAAoAMAIA4AAKEDACAPAACiAwAgngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAAAAAcEBIAAAAAHCASAAAAABwwFAAAAAAcQBAQAAAAEEHAAAkQMAMM0BAACSAwAwzwEAAJQDACDTAQAAlQMAMAQcAACFAwAwzQEAAIYDADDPAQAAiAMAINMBAACJAwAwBBwAAPwCADDNAQAA_QIAMM8BAAD_AgAg0wEAAPQCADAEHAAA8AIAMM0BAADxAgAwzwEAAPMCACDTAQAA9AIAMAQcAADkAgAwzQEAAOUCADDPAQAA5wIAINMBAADoAgAwBBwAANgCADDNAQAA2QIAMM8BAADbAgAg0wEAANwCADADHAAArAMAIM0BAACtAwAg0wEAAAEAIA4BAACkAwAgBAAApwMAIAkAAKgDACAMAACpAwAgDQAAqQMAIA4AAKoDACAPAACrAwAgtwEAALECACC4AQAAsQIAIL0BAACxAgAgvgEAALECACC_AQAAsQIAIMMBAACxAgAgxAEAALECACAFBQAApAMAIAcAAKYDACC2AQAAsQIAILcBAACxAgAguAEAALECACAAAAAAAAAVAQAAowMAIAkAAJ4DACAMAACfAwAgDQAAoAMAIA4AAKEDACAPAACiAwAgngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb0BAQAAAAG-AQEAAAABvwEBAAAAAcABAQAAAAHBASAAAAABwgEgAAAAAcMBQAAAAAHEAQEAAAABAgAAAAEAIBwAAKwDACAOngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAAAAAcEBIAAAAAHCASAAAAABwwFAAAAAAcQBAQAAAAEKngFAAAAAAaoBQAAAAAGxAQEAAAABsgEBAAAAAbMBAQAAAAG0AQEAAAABtQEBAAAAAbYBAQAAAAG3AUAAAAABuAEBAAAAAQKsAQEAAAABrQECAAAAAQKrAQEAAAABrQECAAAAAQKcAQEAAAABqgFAAAAAAQOcAQEAAAABnQFAAAAAAZ4BQAAAAAEDAAAAAwAgHAAArAMAIB0AALYDACAXAAAAAwAgAQAA0QIAIAkAANMCACAMAADUAgAgDQAA1QIAIA4AANYCACAPAADXAgAgFQAAtgMAIJ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbQBAQCYAgAhtQEBAJgCACG3AUAAtgIAIbgBAQC1AgAhvQEBALUCACG-AQEAtQIAIb8BAQC1AgAhwAEBAJgCACHBASAA0AIAIcIBIADQAgAhwwFAALYCACHEAQEAtQIAIRUBAADRAgAgCQAA0wIAIAwAANQCACANAADVAgAgDgAA1gIAIA8AANcCACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAAowMAIAQAAJ0DACAMAACfAwAgDQAAoAMAIA4AAKEDACAPAACiAwAgngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb0BAQAAAAG-AQEAAAABvwEBAAAAAcABAQAAAAHBASAAAAABwgEgAAAAAcMBQAAAAAHEAQEAAAABAgAAAAEAIBwAALcDACAEnAEBAAAAAZ4BQAAAAAGqAUAAAAABsAEAAACwAQIDAAAAAwAgHAAAtwMAIB0AALwDACAXAAAAAwAgAQAA0QIAIAQAANICACAMAADUAgAgDQAA1QIAIA4AANYCACAPAADXAgAgFQAAvAMAIJ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbQBAQCYAgAhtQEBAJgCACG3AUAAtgIAIbgBAQC1AgAhvQEBALUCACG-AQEAtQIAIb8BAQC1AgAhwAEBAJgCACHBASAA0AIAIcIBIADQAgAhwwFAALYCACHEAQEAtQIAIRUBAADRAgAgBAAA0gIAIAwAANQCACANAADVAgAgDgAA1gIAIA8AANcCACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEMBQAAxQIAIJsBAQAAAAGeAUAAAAABqgFAAAAAAbEBAQAAAAGyAQEAAAABswEBAAAAAbQBAQAAAAG1AQEAAAABtgEBAAAAAbcBQAAAAAG4AQEAAAABAgAAAAkAIBwAAL0DACADAAAABwAgHAAAvQMAIB0AAMEDACAOAAAABwAgBQAAtwIAIBUAAMEDACCbAQEAmAIAIZ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbIBAQCYAgAhswEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtgEBALUCACG3AUAAtgIAIbgBAQC1AgAhDAUAALcCACCbAQEAmAIAIZ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbIBAQCYAgAhswEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtgEBALUCACG3AUAAtgIAIbgBAQC1AgAhFQEAAKMDACAEAACdAwAgCQAAngMAIAwAAJ8DACAOAAChAwAgDwAAogMAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbQBAQAAAAG1AQEAAAABtwFAAAAAAbgBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAAAABwQEgAAAAAcIBIAAAAAHDAUAAAAABxAEBAAAAAQIAAAABACAcAADCAwAgFQEAAKMDACAEAACdAwAgCQAAngMAIA0AAKADACAOAAChAwAgDwAAogMAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbQBAQAAAAG1AQEAAAABtwFAAAAAAbgBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAAAABwQEgAAAAAcIBIAAAAAHDAUAAAAABxAEBAAAAAQIAAAABACAcAADEAwAgAwAAAAMAIBwAAMIDACAdAADIAwAgFwAAAAMAIAEAANECACAEAADSAgAgCQAA0wIAIAwAANQCACAOAADWAgAgDwAA1wIAIBUAAMgDACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAA0QIAIAQAANICACAJAADTAgAgDAAA1AIAIA4AANYCACAPAADXAgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbcBQAC2AgAhuAEBALUCACG9AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhAwAAAAMAIBwAAMQDACAdAADLAwAgFwAAAAMAIAEAANECACAEAADSAgAgCQAA0wIAIA0AANUCACAOAADWAgAgDwAA1wIAIBUAAMsDACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAA0QIAIAQAANICACAJAADTAgAgDQAA1QIAIA4AANYCACAPAADXAgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbcBQAC2AgAhuAEBALUCACG9AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhFQEAAKMDACAEAACdAwAgCQAAngMAIAwAAJ8DACANAACgAwAgDwAAogMAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbQBAQAAAAG1AQEAAAABtwFAAAAAAbgBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAAAABwQEgAAAAAcIBIAAAAAHDAUAAAAABxAEBAAAAAQIAAAABACAcAADMAwAgAwAAAAMAIBwAAMwDACAdAADQAwAgFwAAAAMAIAEAANECACAEAADSAgAgCQAA0wIAIAwAANQCACANAADVAgAgDwAA1wIAIBUAANADACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAA0QIAIAQAANICACAJAADTAgAgDAAA1AIAIA0AANUCACAPAADXAgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbcBQAC2AgAhuAEBALUCACG9AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhFQEAAKMDACAEAACdAwAgCQAAngMAIAwAAJ8DACANAACgAwAgDgAAoQMAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbQBAQAAAAG1AQEAAAABtwFAAAAAAbgBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAAAABwQEgAAAAAcIBIAAAAAHDAUAAAAABxAEBAAAAAQIAAAABACAcAADRAwAgAwAAAAMAIBwAANEDACAdAADVAwAgFwAAAAMAIAEAANECACAEAADSAgAgCQAA0wIAIAwAANQCACANAADVAgAgDgAA1gIAIBUAANUDACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAA0QIAIAQAANICACAJAADTAgAgDAAA1AIAIA0AANUCACAOAADWAgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbcBQAC2AgAhuAEBALUCACG9AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhCAEEAQQGAQgACAkKAgwTBQ0UBQ4YBg8cBwMFAAEHDgMIAAQBBgACAQcPAAIKAAELAAEBBQABAQUAAQYEHQAJHgAMHwANIAAOIQAPIgAAAQEsAQEBMgEDCAANIgAOIwAPAAAAAwgADSIADiMADwAAAAMIABUiABYjABcAAAADCAAVIgAWIwAXAAAAAwgAHSIAHiMAHwAAAAMIAB0iAB4jAB8BBQABAQUAAQMIACQiACUjACYAAAADCAAkIgAlIwAmAQYAAgEGAAIDCAArIgAsIwAtAAAAAwgAKyIALCMALQIKAAELAAECCgABCwABBQgAMiIANSMANnQAM3UANAAAAAAABQgAMiIANSMANnQAM3UANAEFAAEBBQABAwgAOyIAPCMAPQAAAAMIADsiADwjAD0BBQABAQUAAQMIAEIiAEMjAEQAAAADCABCIgBDIwBEEAIBESMBEiQBEyUBFCYBFigBFyoJGCsKGS4BGjAJGzELHjMBHzQBIDUJJDgMJTkQJjsRJzwRKD8RKUARKkERK0MRLEUJLUYSLkgRL0oJMEsTMUwRMk0RM04JNFEUNVIYNlQZN1UZOFgZOVkZOloZO1wZPF4JPV8aPmEZP2MJQGQbQWUZQmYZQ2cJRGocRWsgRmwCR20CSG4CSW8CSnACS3ICTHQJTXUhTncCT3kJUHoiUXsCUnwCU30JVIABI1WBASdWggEDV4MBA1iEAQNZhQEDWoYBA1uIAQNcigEJXYsBKF6NAQNfjwEJYJABKWGRAQNikgEDY5MBCWSWASpllwEuZpgBBWeZAQVomgEFaZsBBWqcAQVrngEFbKABCW2hAS9uowEFb6UBCXCmATBxpwEFcqgBBXOpAQl2rAExd60BN3iuAQZ5rwEGerABBnuxAQZ8sgEGfbQBBn62AQl_twE4gAG5AQaBAbsBCYIBvAE5gwG9AQaEAb4BBoUBvwEJhgHCATqHAcMBPogBxAEHiQHFAQeKAcYBB4sBxwEHjAHIAQeNAcoBB44BzAEJjwHNAT-QAc8BB5EB0QEJkgHSAUCTAdMBB5QB1AEHlQHVAQmWAdgBQZcB2QFF" } config.compilerWasm = { getRuntime: async () => require('./query_compiler_fast_bg.js'), diff --git a/packages/forums-prisma-client/index-browser.js b/packages/forums-prisma-client/index-browser.js index 2b3aa09..1995440 100644 --- a/packages/forums-prisma-client/index-browser.js +++ b/packages/forums-prisma-client/index-browser.js @@ -170,6 +170,14 @@ exports.Prisma.PostScalarFieldEnum = { deletedByMemberId: 'deletedByMemberId' }; +exports.Prisma.PostReactionScalarFieldEnum = { + postId: 'postId', + memberId: 'memberId', + reaction: 'reaction', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +}; + exports.Prisma.TopicClosureScalarFieldEnum = { ancestorTopicId: 'ancestorTopicId', descendantTopicId: 'descendantTopicId', @@ -203,13 +211,17 @@ exports.Prisma.NullsOrder = { first: 'first', last: 'last' }; - +exports.PostReactionType = exports.$Enums.PostReactionType = { + THUMBS_UP: 'THUMBS_UP', + THUMBS_DOWN: 'THUMBS_DOWN' +}; exports.Prisma.ModelName = { Topic: 'Topic', MemberBan: 'MemberBan', IpBan: 'IpBan', Post: 'Post', + PostReaction: 'PostReaction', TopicClosure: 'TopicClosure', TopicWatch: 'TopicWatch', TopicReadState: 'TopicReadState' diff --git a/packages/forums-prisma-client/index.d.ts b/packages/forums-prisma-client/index.d.ts index b7d370e..7f5014b 100644 --- a/packages/forums-prisma-client/index.d.ts +++ b/packages/forums-prisma-client/index.d.ts @@ -33,6 +33,11 @@ export type IpBan = $Result.DefaultSelection * */ export type Post = $Result.DefaultSelection +/** + * Model PostReaction + * + */ +export type PostReaction = $Result.DefaultSelection /** * Model TopicClosure * @@ -49,6 +54,23 @@ export type TopicWatch = $Result.DefaultSelection */ export type TopicReadState = $Result.DefaultSelection +/** + * Enums + */ +export namespace $Enums { + export const PostReactionType: { + THUMBS_UP: 'THUMBS_UP', + THUMBS_DOWN: 'THUMBS_DOWN' +}; + +export type PostReactionType = (typeof PostReactionType)[keyof typeof PostReactionType] + +} + +export type PostReactionType = $Enums.PostReactionType + +export const PostReactionType: typeof $Enums.PostReactionType + /** * ## Prisma Client ʲˢ * @@ -210,6 +232,16 @@ export class PrismaClient< */ get post(): Prisma.PostDelegate; + /** + * `prisma.postReaction`: Exposes CRUD operations for the **PostReaction** model. + * Example usage: + * ```ts + * // Fetch zero or more PostReactions + * const postReactions = await prisma.postReaction.findMany() + * ``` + */ + get postReaction(): Prisma.PostReactionDelegate; + /** * `prisma.topicClosure`: Exposes CRUD operations for the **TopicClosure** model. * Example usage: @@ -690,6 +722,7 @@ export namespace Prisma { MemberBan: 'MemberBan', IpBan: 'IpBan', Post: 'Post', + PostReaction: 'PostReaction', TopicClosure: 'TopicClosure', TopicWatch: 'TopicWatch', TopicReadState: 'TopicReadState' @@ -708,7 +741,7 @@ export namespace Prisma { omit: GlobalOmitOptions } meta: { - modelProps: "topic" | "memberBan" | "ipBan" | "post" | "topicClosure" | "topicWatch" | "topicReadState" + modelProps: "topic" | "memberBan" | "ipBan" | "post" | "postReaction" | "topicClosure" | "topicWatch" | "topicReadState" txIsolationLevel: Prisma.TransactionIsolationLevel } model: { @@ -1008,6 +1041,80 @@ export namespace Prisma { } } } + PostReaction: { + payload: Prisma.$PostReactionPayload + fields: Prisma.PostReactionFieldRefs + operations: { + findUnique: { + args: Prisma.PostReactionFindUniqueArgs + result: $Utils.PayloadToResult | null + } + findUniqueOrThrow: { + args: Prisma.PostReactionFindUniqueOrThrowArgs + result: $Utils.PayloadToResult + } + findFirst: { + args: Prisma.PostReactionFindFirstArgs + result: $Utils.PayloadToResult | null + } + findFirstOrThrow: { + args: Prisma.PostReactionFindFirstOrThrowArgs + result: $Utils.PayloadToResult + } + findMany: { + args: Prisma.PostReactionFindManyArgs + result: $Utils.PayloadToResult[] + } + create: { + args: Prisma.PostReactionCreateArgs + result: $Utils.PayloadToResult + } + createMany: { + args: Prisma.PostReactionCreateManyArgs + result: BatchPayload + } + createManyAndReturn: { + args: Prisma.PostReactionCreateManyAndReturnArgs + result: $Utils.PayloadToResult[] + } + delete: { + args: Prisma.PostReactionDeleteArgs + result: $Utils.PayloadToResult + } + update: { + args: Prisma.PostReactionUpdateArgs + result: $Utils.PayloadToResult + } + deleteMany: { + args: Prisma.PostReactionDeleteManyArgs + result: BatchPayload + } + updateMany: { + args: Prisma.PostReactionUpdateManyArgs + result: BatchPayload + } + updateManyAndReturn: { + args: Prisma.PostReactionUpdateManyAndReturnArgs + result: $Utils.PayloadToResult[] + } + upsert: { + args: Prisma.PostReactionUpsertArgs + result: $Utils.PayloadToResult + } + aggregate: { + args: Prisma.PostReactionAggregateArgs + result: $Utils.Optional + } + groupBy: { + args: Prisma.PostReactionGroupByArgs + result: $Utils.Optional[] + } + count: { + args: Prisma.PostReactionCountArgs + result: $Utils.Optional | number + } + } + } TopicClosure: { payload: Prisma.$TopicClosurePayload fields: Prisma.TopicClosureFieldRefs @@ -1357,6 +1464,7 @@ export namespace Prisma { memberBan?: MemberBanOmit ipBan?: IpBanOmit post?: PostOmit + postReaction?: PostReactionOmit topicClosure?: TopicClosureOmit topicWatch?: TopicWatchOmit topicReadState?: TopicReadStateOmit @@ -1511,6 +1619,37 @@ export namespace Prisma { } + /** + * Count Type PostCountOutputType + */ + + export type PostCountOutputType = { + reactions: number + } + + export type PostCountOutputTypeSelect = { + reactions?: boolean | PostCountOutputTypeCountReactionsArgs + } + + // Custom InputTypes + /** + * PostCountOutputType without action + */ + export type PostCountOutputTypeDefaultArgs = { + /** + * Select specific fields to fetch from the PostCountOutputType + */ + select?: PostCountOutputTypeSelect | null + } + + /** + * PostCountOutputType without action + */ + export type PostCountOutputTypeCountReactionsArgs = { + where?: PostReactionWhereInput + } + + /** * Models */ @@ -5136,6 +5275,8 @@ export namespace Prisma { deletedAt?: boolean deletedByMemberId?: boolean topic?: boolean | TopicDefaultArgs + reactions?: boolean | Post$reactionsArgs + _count?: boolean | PostCountOutputTypeDefaultArgs }, ExtArgs["result"]["post"]> export type PostSelectCreateManyAndReturn = $Extensions.GetSelect<{ @@ -5185,6 +5326,8 @@ export namespace Prisma { export type PostOmit = $Extensions.GetOmit<"id" | "topicId" | "parentType" | "parentId" | "authorMemberId" | "authorHandle" | "content" | "createdAt" | "updatedAt" | "deletedAt" | "deletedByMemberId", ExtArgs["result"]["post"]> export type PostInclude = { topic?: boolean | TopicDefaultArgs + reactions?: boolean | Post$reactionsArgs + _count?: boolean | PostCountOutputTypeDefaultArgs } export type PostIncludeCreateManyAndReturn = { topic?: boolean | TopicDefaultArgs @@ -5197,6 +5340,7 @@ export namespace Prisma { name: "Post" objects: { topic: Prisma.$TopicPayload + reactions: Prisma.$PostReactionPayload[] } scalars: $Extensions.GetPayloadResult<{ id: string @@ -5605,6 +5749,7 @@ export namespace Prisma { export interface Prisma__PostClient extends Prisma.PrismaPromise { readonly [Symbol.toStringTag]: "PrismaPromise" topic = {}>(args?: Subset>): Prisma__TopicClient<$Result.GetResult, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions> + reactions = {}>(args?: Subset>): Prisma.PrismaPromise<$Result.GetResult, T, "findMany", GlobalOmitOptions> | Null> /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. @@ -5964,103 +6109,1190 @@ export namespace Prisma { /** * The data used to update Posts. */ - data: XOR + data: XOR + /** + * Filter which Posts to update + */ + where?: PostWhereInput + /** + * Limit how many Posts to update. + */ + limit?: number + /** + * Choose, which related nodes to fetch as well + */ + include?: PostIncludeUpdateManyAndReturn | null + } + + /** + * Post upsert + */ + export type PostUpsertArgs = { + /** + * Select specific fields to fetch from the Post + */ + select?: PostSelect | null + /** + * Omit specific fields from the Post + */ + omit?: PostOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostInclude | null + /** + * The filter to search for the Post to update in case it exists. + */ + where: PostWhereUniqueInput + /** + * In case the Post found by the `where` argument doesn't exist, create a new Post with this data. + */ + create: XOR + /** + * In case the Post was found with the provided `where` argument, update it with this data. + */ + update: XOR + } + + /** + * Post delete + */ + export type PostDeleteArgs = { + /** + * Select specific fields to fetch from the Post + */ + select?: PostSelect | null + /** + * Omit specific fields from the Post + */ + omit?: PostOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostInclude | null + /** + * Filter which Post to delete. + */ + where: PostWhereUniqueInput + } + + /** + * Post deleteMany + */ + export type PostDeleteManyArgs = { + /** + * Filter which Posts to delete + */ + where?: PostWhereInput + /** + * Limit how many Posts to delete. + */ + limit?: number + } + + /** + * Post.reactions + */ + export type Post$reactionsArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelect | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionInclude | null + where?: PostReactionWhereInput + orderBy?: PostReactionOrderByWithRelationInput | PostReactionOrderByWithRelationInput[] + cursor?: PostReactionWhereUniqueInput + take?: number + skip?: number + distinct?: PostReactionScalarFieldEnum | PostReactionScalarFieldEnum[] + } + + /** + * Post without action + */ + export type PostDefaultArgs = { + /** + * Select specific fields to fetch from the Post + */ + select?: PostSelect | null + /** + * Omit specific fields from the Post + */ + omit?: PostOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostInclude | null + } + + + /** + * Model PostReaction + */ + + export type AggregatePostReaction = { + _count: PostReactionCountAggregateOutputType | null + _min: PostReactionMinAggregateOutputType | null + _max: PostReactionMaxAggregateOutputType | null + } + + export type PostReactionMinAggregateOutputType = { + postId: string | null + memberId: string | null + reaction: $Enums.PostReactionType | null + createdAt: Date | null + updatedAt: Date | null + } + + export type PostReactionMaxAggregateOutputType = { + postId: string | null + memberId: string | null + reaction: $Enums.PostReactionType | null + createdAt: Date | null + updatedAt: Date | null + } + + export type PostReactionCountAggregateOutputType = { + postId: number + memberId: number + reaction: number + createdAt: number + updatedAt: number + _all: number + } + + + export type PostReactionMinAggregateInputType = { + postId?: true + memberId?: true + reaction?: true + createdAt?: true + updatedAt?: true + } + + export type PostReactionMaxAggregateInputType = { + postId?: true + memberId?: true + reaction?: true + createdAt?: true + updatedAt?: true + } + + export type PostReactionCountAggregateInputType = { + postId?: true + memberId?: true + reaction?: true + createdAt?: true + updatedAt?: true + _all?: true + } + + export type PostReactionAggregateArgs = { + /** + * Filter which PostReaction to aggregate. + */ + where?: PostReactionWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of PostReactions to fetch. + */ + orderBy?: PostReactionOrderByWithRelationInput | PostReactionOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the start position + */ + cursor?: PostReactionWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` PostReactions from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` PostReactions. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Count returned PostReactions + **/ + _count?: true | PostReactionCountAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the minimum value + **/ + _min?: PostReactionMinAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the maximum value + **/ + _max?: PostReactionMaxAggregateInputType + } + + export type GetPostReactionAggregateType = { + [P in keyof T & keyof AggregatePostReaction]: P extends '_count' | 'count' + ? T[P] extends true + ? number + : GetScalarType + : GetScalarType + } + + + + + export type PostReactionGroupByArgs = { + where?: PostReactionWhereInput + orderBy?: PostReactionOrderByWithAggregationInput | PostReactionOrderByWithAggregationInput[] + by: PostReactionScalarFieldEnum[] | PostReactionScalarFieldEnum + having?: PostReactionScalarWhereWithAggregatesInput + take?: number + skip?: number + _count?: PostReactionCountAggregateInputType | true + _min?: PostReactionMinAggregateInputType + _max?: PostReactionMaxAggregateInputType + } + + export type PostReactionGroupByOutputType = { + postId: string + memberId: string + reaction: $Enums.PostReactionType + createdAt: Date + updatedAt: Date + _count: PostReactionCountAggregateOutputType | null + _min: PostReactionMinAggregateOutputType | null + _max: PostReactionMaxAggregateOutputType | null + } + + type GetPostReactionGroupByPayload = Prisma.PrismaPromise< + Array< + PickEnumerable & + { + [P in ((keyof T) & (keyof PostReactionGroupByOutputType))]: P extends '_count' + ? T[P] extends boolean + ? number + : GetScalarType + : GetScalarType + } + > + > + + + export type PostReactionSelect = $Extensions.GetSelect<{ + postId?: boolean + memberId?: boolean + reaction?: boolean + createdAt?: boolean + updatedAt?: boolean + post?: boolean | PostDefaultArgs + }, ExtArgs["result"]["postReaction"]> + + export type PostReactionSelectCreateManyAndReturn = $Extensions.GetSelect<{ + postId?: boolean + memberId?: boolean + reaction?: boolean + createdAt?: boolean + updatedAt?: boolean + post?: boolean | PostDefaultArgs + }, ExtArgs["result"]["postReaction"]> + + export type PostReactionSelectUpdateManyAndReturn = $Extensions.GetSelect<{ + postId?: boolean + memberId?: boolean + reaction?: boolean + createdAt?: boolean + updatedAt?: boolean + post?: boolean | PostDefaultArgs + }, ExtArgs["result"]["postReaction"]> + + export type PostReactionSelectScalar = { + postId?: boolean + memberId?: boolean + reaction?: boolean + createdAt?: boolean + updatedAt?: boolean + } + + export type PostReactionOmit = $Extensions.GetOmit<"postId" | "memberId" | "reaction" | "createdAt" | "updatedAt", ExtArgs["result"]["postReaction"]> + export type PostReactionInclude = { + post?: boolean | PostDefaultArgs + } + export type PostReactionIncludeCreateManyAndReturn = { + post?: boolean | PostDefaultArgs + } + export type PostReactionIncludeUpdateManyAndReturn = { + post?: boolean | PostDefaultArgs + } + + export type $PostReactionPayload = { + name: "PostReaction" + objects: { + post: Prisma.$PostPayload + } + scalars: $Extensions.GetPayloadResult<{ + postId: string + memberId: string + reaction: $Enums.PostReactionType + createdAt: Date + updatedAt: Date + }, ExtArgs["result"]["postReaction"]> + composites: {} + } + + type PostReactionGetPayload = $Result.GetResult + + type PostReactionCountArgs = + Omit & { + select?: PostReactionCountAggregateInputType | true + } + + export interface PostReactionDelegate { + [K: symbol]: { types: Prisma.TypeMap['model']['PostReaction'], meta: { name: 'PostReaction' } } + /** + * Find zero or one PostReaction that matches the filter. + * @param {PostReactionFindUniqueArgs} args - Arguments to find a PostReaction + * @example + * // Get one PostReaction + * const postReaction = await prisma.postReaction.findUnique({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUnique(args: SelectSubset>): Prisma__PostReactionClient<$Result.GetResult, T, "findUnique", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find one PostReaction that matches the filter or throw an error with `error.code='P2025'` + * if no matches were found. + * @param {PostReactionFindUniqueOrThrowArgs} args - Arguments to find a PostReaction + * @example + * // Get one PostReaction + * const postReaction = await prisma.postReaction.findUniqueOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUniqueOrThrow(args: SelectSubset>): Prisma__PostReactionClient<$Result.GetResult, T, "findUniqueOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find the first PostReaction that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {PostReactionFindFirstArgs} args - Arguments to find a PostReaction + * @example + * // Get one PostReaction + * const postReaction = await prisma.postReaction.findFirst({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirst(args?: SelectSubset>): Prisma__PostReactionClient<$Result.GetResult, T, "findFirst", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find the first PostReaction that matches the filter or + * throw `PrismaKnownClientError` with `P2025` code if no matches were found. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {PostReactionFindFirstOrThrowArgs} args - Arguments to find a PostReaction + * @example + * // Get one PostReaction + * const postReaction = await prisma.postReaction.findFirstOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirstOrThrow(args?: SelectSubset>): Prisma__PostReactionClient<$Result.GetResult, T, "findFirstOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find zero or more PostReactions that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {PostReactionFindManyArgs} args - Arguments to filter and select certain fields only. + * @example + * // Get all PostReactions + * const postReactions = await prisma.postReaction.findMany() + * + * // Get first 10 PostReactions + * const postReactions = await prisma.postReaction.findMany({ take: 10 }) + * + * // Only select the `postId` + * const postReactionWithPostIdOnly = await prisma.postReaction.findMany({ select: { postId: true } }) + * + */ + findMany(args?: SelectSubset>): Prisma.PrismaPromise<$Result.GetResult, T, "findMany", GlobalOmitOptions>> + + /** + * Create a PostReaction. + * @param {PostReactionCreateArgs} args - Arguments to create a PostReaction. + * @example + * // Create one PostReaction + * const PostReaction = await prisma.postReaction.create({ + * data: { + * // ... data to create a PostReaction + * } + * }) + * + */ + create(args: SelectSubset>): Prisma__PostReactionClient<$Result.GetResult, T, "create", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Create many PostReactions. + * @param {PostReactionCreateManyArgs} args - Arguments to create many PostReactions. + * @example + * // Create many PostReactions + * const postReaction = await prisma.postReaction.createMany({ + * data: [ + * // ... provide data here + * ] + * }) + * + */ + createMany(args?: SelectSubset>): Prisma.PrismaPromise + + /** + * Create many PostReactions and returns the data saved in the database. + * @param {PostReactionCreateManyAndReturnArgs} args - Arguments to create many PostReactions. + * @example + * // Create many PostReactions + * const postReaction = await prisma.postReaction.createManyAndReturn({ + * data: [ + * // ... provide data here + * ] + * }) + * + * // Create many PostReactions and only return the `postId` + * const postReactionWithPostIdOnly = await prisma.postReaction.createManyAndReturn({ + * select: { postId: true }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + createManyAndReturn(args?: SelectSubset>): Prisma.PrismaPromise<$Result.GetResult, T, "createManyAndReturn", GlobalOmitOptions>> + + /** + * Delete a PostReaction. + * @param {PostReactionDeleteArgs} args - Arguments to delete one PostReaction. + * @example + * // Delete one PostReaction + * const PostReaction = await prisma.postReaction.delete({ + * where: { + * // ... filter to delete one PostReaction + * } + * }) + * + */ + delete(args: SelectSubset>): Prisma__PostReactionClient<$Result.GetResult, T, "delete", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Update one PostReaction. + * @param {PostReactionUpdateArgs} args - Arguments to update one PostReaction. + * @example + * // Update one PostReaction + * const postReaction = await prisma.postReaction.update({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + update(args: SelectSubset>): Prisma__PostReactionClient<$Result.GetResult, T, "update", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Delete zero or more PostReactions. + * @param {PostReactionDeleteManyArgs} args - Arguments to filter PostReactions to delete. + * @example + * // Delete a few PostReactions + * const { count } = await prisma.postReaction.deleteMany({ + * where: { + * // ... provide filter here + * } + * }) + * + */ + deleteMany(args?: SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more PostReactions. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {PostReactionUpdateManyArgs} args - Arguments to update one or more rows. + * @example + * // Update many PostReactions + * const postReaction = await prisma.postReaction.updateMany({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + updateMany(args: SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more PostReactions and returns the data updated in the database. + * @param {PostReactionUpdateManyAndReturnArgs} args - Arguments to update many PostReactions. + * @example + * // Update many PostReactions + * const postReaction = await prisma.postReaction.updateManyAndReturn({ + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * + * // Update zero or more PostReactions and only return the `postId` + * const postReactionWithPostIdOnly = await prisma.postReaction.updateManyAndReturn({ + * select: { postId: true }, + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + updateManyAndReturn(args: SelectSubset>): Prisma.PrismaPromise<$Result.GetResult, T, "updateManyAndReturn", GlobalOmitOptions>> + + /** + * Create or update one PostReaction. + * @param {PostReactionUpsertArgs} args - Arguments to update or create a PostReaction. + * @example + * // Update or create a PostReaction + * const postReaction = await prisma.postReaction.upsert({ + * create: { + * // ... data to create a PostReaction + * }, + * update: { + * // ... in case it already exists, update + * }, + * where: { + * // ... the filter for the PostReaction we want to update + * } + * }) + */ + upsert(args: SelectSubset>): Prisma__PostReactionClient<$Result.GetResult, T, "upsert", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + + /** + * Count the number of PostReactions. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {PostReactionCountArgs} args - Arguments to filter PostReactions to count. + * @example + * // Count the number of PostReactions + * const count = await prisma.postReaction.count({ + * where: { + * // ... the filter for the PostReactions we want to count + * } + * }) + **/ + count( + args?: Subset, + ): Prisma.PrismaPromise< + T extends $Utils.Record<'select', any> + ? T['select'] extends true + ? number + : GetScalarType + : number + > + + /** + * Allows you to perform aggregations operations on a PostReaction. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {PostReactionAggregateArgs} args - Select which aggregations you would like to apply and on what fields. + * @example + * // Ordered by age ascending + * // Where email contains prisma.io + * // Limited to the 10 users + * const aggregations = await prisma.user.aggregate({ + * _avg: { + * age: true, + * }, + * where: { + * email: { + * contains: "prisma.io", + * }, + * }, + * orderBy: { + * age: "asc", + * }, + * take: 10, + * }) + **/ + aggregate(args: Subset): Prisma.PrismaPromise> + + /** + * Group by PostReaction. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {PostReactionGroupByArgs} args - Group by arguments. + * @example + * // Group by city, order by createdAt, get count + * const result = await prisma.user.groupBy({ + * by: ['city', 'createdAt'], + * orderBy: { + * createdAt: true + * }, + * _count: { + * _all: true + * }, + * }) + * + **/ + groupBy< + T extends PostReactionGroupByArgs, + HasSelectOrTake extends Or< + Extends<'skip', Keys>, + Extends<'take', Keys> + >, + OrderByArg extends True extends HasSelectOrTake + ? { orderBy: PostReactionGroupByArgs['orderBy'] } + : { orderBy?: PostReactionGroupByArgs['orderBy'] }, + OrderFields extends ExcludeUnderscoreKeys>>, + ByFields extends MaybeTupleToUnion, + ByValid extends Has, + HavingFields extends GetHavingFields, + HavingValid extends Has, + ByEmpty extends T['by'] extends never[] ? True : False, + InputErrors extends ByEmpty extends True + ? `Error: "by" must not be empty.` + : HavingValid extends False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Keys + ? 'orderBy' extends Keys + ? ByValid extends True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Keys + ? 'orderBy' extends Keys + ? ByValid extends True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(args: SubsetIntersection & InputErrors): {} extends InputErrors ? GetPostReactionGroupByPayload : Prisma.PrismaPromise + /** + * Fields of the PostReaction model + */ + readonly fields: PostReactionFieldRefs; + } + + /** + * The delegate class that acts as a "Promise-like" for PostReaction. + * Why is this prefixed with `Prisma__`? + * Because we want to prevent naming conflicts as mentioned in + * https://github.com/prisma/prisma-client-js/issues/707 + */ + export interface Prisma__PostReactionClient extends Prisma.PrismaPromise { + readonly [Symbol.toStringTag]: "PrismaPromise" + post = {}>(args?: Subset>): Prisma__PostClient<$Result.GetResult, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions> + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): $Utils.JsPromise + /** + * Attaches a callback for only the rejection of the Promise. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of the callback. + */ + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): $Utils.JsPromise + /** + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The + * resolved value cannot be modified from the callback. + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). + * @returns A Promise for the completion of the callback. + */ + finally(onfinally?: (() => void) | undefined | null): $Utils.JsPromise + } + + + + + /** + * Fields of the PostReaction model + */ + interface PostReactionFieldRefs { + readonly postId: FieldRef<"PostReaction", 'String'> + readonly memberId: FieldRef<"PostReaction", 'String'> + readonly reaction: FieldRef<"PostReaction", 'PostReactionType'> + readonly createdAt: FieldRef<"PostReaction", 'DateTime'> + readonly updatedAt: FieldRef<"PostReaction", 'DateTime'> + } + + + // Custom InputTypes + /** + * PostReaction findUnique + */ + export type PostReactionFindUniqueArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelect | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionInclude | null + /** + * Filter, which PostReaction to fetch. + */ + where: PostReactionWhereUniqueInput + } + + /** + * PostReaction findUniqueOrThrow + */ + export type PostReactionFindUniqueOrThrowArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelect | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionInclude | null + /** + * Filter, which PostReaction to fetch. + */ + where: PostReactionWhereUniqueInput + } + + /** + * PostReaction findFirst + */ + export type PostReactionFindFirstArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelect | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionInclude | null + /** + * Filter, which PostReaction to fetch. + */ + where?: PostReactionWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of PostReactions to fetch. + */ + orderBy?: PostReactionOrderByWithRelationInput | PostReactionOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for PostReactions. + */ + cursor?: PostReactionWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` PostReactions from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` PostReactions. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of PostReactions. + */ + distinct?: PostReactionScalarFieldEnum | PostReactionScalarFieldEnum[] + } + + /** + * PostReaction findFirstOrThrow + */ + export type PostReactionFindFirstOrThrowArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelect | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionInclude | null + /** + * Filter, which PostReaction to fetch. + */ + where?: PostReactionWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of PostReactions to fetch. + */ + orderBy?: PostReactionOrderByWithRelationInput | PostReactionOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for PostReactions. + */ + cursor?: PostReactionWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` PostReactions from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` PostReactions. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of PostReactions. + */ + distinct?: PostReactionScalarFieldEnum | PostReactionScalarFieldEnum[] + } + + /** + * PostReaction findMany + */ + export type PostReactionFindManyArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelect | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionInclude | null + /** + * Filter, which PostReactions to fetch. + */ + where?: PostReactionWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of PostReactions to fetch. + */ + orderBy?: PostReactionOrderByWithRelationInput | PostReactionOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for listing PostReactions. + */ + cursor?: PostReactionWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` PostReactions from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` PostReactions. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of PostReactions. + */ + distinct?: PostReactionScalarFieldEnum | PostReactionScalarFieldEnum[] + } + + /** + * PostReaction create + */ + export type PostReactionCreateArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelect | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionInclude | null + /** + * The data needed to create a PostReaction. + */ + data: XOR + } + + /** + * PostReaction createMany + */ + export type PostReactionCreateManyArgs = { + /** + * The data used to create many PostReactions. + */ + data: PostReactionCreateManyInput | PostReactionCreateManyInput[] + skipDuplicates?: boolean + } + + /** + * PostReaction createManyAndReturn + */ + export type PostReactionCreateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelectCreateManyAndReturn | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * The data used to create many PostReactions. + */ + data: PostReactionCreateManyInput | PostReactionCreateManyInput[] + skipDuplicates?: boolean + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionIncludeCreateManyAndReturn | null + } + + /** + * PostReaction update + */ + export type PostReactionUpdateArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelect | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: PostReactionInclude | null + /** + * The data needed to update a PostReaction. + */ + data: XOR + /** + * Choose, which PostReaction to update. + */ + where: PostReactionWhereUniqueInput + } + + /** + * PostReaction updateMany + */ + export type PostReactionUpdateManyArgs = { + /** + * The data used to update PostReactions. + */ + data: XOR + /** + * Filter which PostReactions to update + */ + where?: PostReactionWhereInput + /** + * Limit how many PostReactions to update. + */ + limit?: number + } + + /** + * PostReaction updateManyAndReturn + */ + export type PostReactionUpdateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the PostReaction + */ + select?: PostReactionSelectUpdateManyAndReturn | null + /** + * Omit specific fields from the PostReaction + */ + omit?: PostReactionOmit | null + /** + * The data used to update PostReactions. + */ + data: XOR /** - * Filter which Posts to update + * Filter which PostReactions to update */ - where?: PostWhereInput + where?: PostReactionWhereInput /** - * Limit how many Posts to update. + * Limit how many PostReactions to update. */ limit?: number /** * Choose, which related nodes to fetch as well */ - include?: PostIncludeUpdateManyAndReturn | null + include?: PostReactionIncludeUpdateManyAndReturn | null } /** - * Post upsert + * PostReaction upsert */ - export type PostUpsertArgs = { + export type PostReactionUpsertArgs = { /** - * Select specific fields to fetch from the Post + * Select specific fields to fetch from the PostReaction */ - select?: PostSelect | null + select?: PostReactionSelect | null /** - * Omit specific fields from the Post + * Omit specific fields from the PostReaction */ - omit?: PostOmit | null + omit?: PostReactionOmit | null /** * Choose, which related nodes to fetch as well */ - include?: PostInclude | null + include?: PostReactionInclude | null /** - * The filter to search for the Post to update in case it exists. + * The filter to search for the PostReaction to update in case it exists. */ - where: PostWhereUniqueInput + where: PostReactionWhereUniqueInput /** - * In case the Post found by the `where` argument doesn't exist, create a new Post with this data. + * In case the PostReaction found by the `where` argument doesn't exist, create a new PostReaction with this data. */ - create: XOR + create: XOR /** - * In case the Post was found with the provided `where` argument, update it with this data. + * In case the PostReaction was found with the provided `where` argument, update it with this data. */ - update: XOR + update: XOR } /** - * Post delete + * PostReaction delete */ - export type PostDeleteArgs = { + export type PostReactionDeleteArgs = { /** - * Select specific fields to fetch from the Post + * Select specific fields to fetch from the PostReaction */ - select?: PostSelect | null + select?: PostReactionSelect | null /** - * Omit specific fields from the Post + * Omit specific fields from the PostReaction */ - omit?: PostOmit | null + omit?: PostReactionOmit | null /** * Choose, which related nodes to fetch as well */ - include?: PostInclude | null + include?: PostReactionInclude | null /** - * Filter which Post to delete. + * Filter which PostReaction to delete. */ - where: PostWhereUniqueInput + where: PostReactionWhereUniqueInput } /** - * Post deleteMany + * PostReaction deleteMany */ - export type PostDeleteManyArgs = { + export type PostReactionDeleteManyArgs = { /** - * Filter which Posts to delete + * Filter which PostReactions to delete */ - where?: PostWhereInput + where?: PostReactionWhereInput /** - * Limit how many Posts to delete. + * Limit how many PostReactions to delete. */ limit?: number } /** - * Post without action + * PostReaction without action */ - export type PostDefaultArgs = { + export type PostReactionDefaultArgs = { /** - * Select specific fields to fetch from the Post + * Select specific fields to fetch from the PostReaction */ - select?: PostSelect | null + select?: PostReactionSelect | null /** - * Omit specific fields from the Post + * Omit specific fields from the PostReaction */ - omit?: PostOmit | null + omit?: PostReactionOmit | null /** * Choose, which related nodes to fetch as well */ - include?: PostInclude | null + include?: PostReactionInclude | null } @@ -9306,6 +10538,17 @@ export namespace Prisma { export type PostScalarFieldEnum = (typeof PostScalarFieldEnum)[keyof typeof PostScalarFieldEnum] + export const PostReactionScalarFieldEnum: { + postId: 'postId', + memberId: 'memberId', + reaction: 'reaction', + createdAt: 'createdAt', + updatedAt: 'updatedAt' + }; + + export type PostReactionScalarFieldEnum = (typeof PostReactionScalarFieldEnum)[keyof typeof PostReactionScalarFieldEnum] + + export const TopicClosureScalarFieldEnum: { ancestorTopicId: 'ancestorTopicId', descendantTopicId: 'descendantTopicId', @@ -9398,6 +10641,20 @@ export namespace Prisma { + /** + * Reference to a field of type 'PostReactionType' + */ + export type EnumPostReactionTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'PostReactionType'> + + + + /** + * Reference to a field of type 'PostReactionType[]' + */ + export type ListEnumPostReactionTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'PostReactionType[]'> + + + /** * Reference to a field of type 'Int' */ @@ -9682,6 +10939,7 @@ export namespace Prisma { deletedAt?: DateTimeNullableFilter<"Post"> | Date | string | null deletedByMemberId?: StringNullableFilter<"Post"> | string | null topic?: XOR + reactions?: PostReactionListRelationFilter } export type PostOrderByWithRelationInput = { @@ -9697,6 +10955,7 @@ export namespace Prisma { deletedAt?: SortOrderInput | SortOrder deletedByMemberId?: SortOrderInput | SortOrder topic?: TopicOrderByWithRelationInput + reactions?: PostReactionOrderByRelationAggregateInput } export type PostWhereUniqueInput = Prisma.AtLeast<{ @@ -9715,6 +10974,7 @@ export namespace Prisma { deletedAt?: DateTimeNullableFilter<"Post"> | Date | string | null deletedByMemberId?: StringNullableFilter<"Post"> | string | null topic?: XOR + reactions?: PostReactionListRelationFilter }, "id"> export type PostOrderByWithAggregationInput = { @@ -9751,6 +11011,62 @@ export namespace Prisma { deletedByMemberId?: StringNullableWithAggregatesFilter<"Post"> | string | null } + export type PostReactionWhereInput = { + AND?: PostReactionWhereInput | PostReactionWhereInput[] + OR?: PostReactionWhereInput[] + NOT?: PostReactionWhereInput | PostReactionWhereInput[] + postId?: StringFilter<"PostReaction"> | string + memberId?: StringFilter<"PostReaction"> | string + reaction?: EnumPostReactionTypeFilter<"PostReaction"> | $Enums.PostReactionType + createdAt?: DateTimeFilter<"PostReaction"> | Date | string + updatedAt?: DateTimeFilter<"PostReaction"> | Date | string + post?: XOR + } + + export type PostReactionOrderByWithRelationInput = { + postId?: SortOrder + memberId?: SortOrder + reaction?: SortOrder + createdAt?: SortOrder + updatedAt?: SortOrder + post?: PostOrderByWithRelationInput + } + + export type PostReactionWhereUniqueInput = Prisma.AtLeast<{ + postId_memberId?: PostReactionPostIdMemberIdCompoundUniqueInput + AND?: PostReactionWhereInput | PostReactionWhereInput[] + OR?: PostReactionWhereInput[] + NOT?: PostReactionWhereInput | PostReactionWhereInput[] + postId?: StringFilter<"PostReaction"> | string + memberId?: StringFilter<"PostReaction"> | string + reaction?: EnumPostReactionTypeFilter<"PostReaction"> | $Enums.PostReactionType + createdAt?: DateTimeFilter<"PostReaction"> | Date | string + updatedAt?: DateTimeFilter<"PostReaction"> | Date | string + post?: XOR + }, "postId_memberId"> + + export type PostReactionOrderByWithAggregationInput = { + postId?: SortOrder + memberId?: SortOrder + reaction?: SortOrder + createdAt?: SortOrder + updatedAt?: SortOrder + _count?: PostReactionCountOrderByAggregateInput + _max?: PostReactionMaxOrderByAggregateInput + _min?: PostReactionMinOrderByAggregateInput + } + + export type PostReactionScalarWhereWithAggregatesInput = { + AND?: PostReactionScalarWhereWithAggregatesInput | PostReactionScalarWhereWithAggregatesInput[] + OR?: PostReactionScalarWhereWithAggregatesInput[] + NOT?: PostReactionScalarWhereWithAggregatesInput | PostReactionScalarWhereWithAggregatesInput[] + postId?: StringWithAggregatesFilter<"PostReaction"> | string + memberId?: StringWithAggregatesFilter<"PostReaction"> | string + reaction?: EnumPostReactionTypeWithAggregatesFilter<"PostReaction"> | $Enums.PostReactionType + createdAt?: DateTimeWithAggregatesFilter<"PostReaction"> | Date | string + updatedAt?: DateTimeWithAggregatesFilter<"PostReaction"> | Date | string + } + export type TopicClosureWhereInput = { AND?: TopicClosureWhereInput | TopicClosureWhereInput[] OR?: TopicClosureWhereInput[] @@ -10186,6 +11502,7 @@ export namespace Prisma { deletedAt?: Date | string | null deletedByMemberId?: string | null topic: TopicCreateNestedOneWithoutPostsInput + reactions?: PostReactionCreateNestedManyWithoutPostInput } export type PostUncheckedCreateInput = { @@ -10200,6 +11517,7 @@ export namespace Prisma { updatedAt?: Date | string deletedAt?: Date | string | null deletedByMemberId?: string | null + reactions?: PostReactionUncheckedCreateNestedManyWithoutPostInput } export type PostUpdateInput = { @@ -10214,6 +11532,7 @@ export namespace Prisma { deletedAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null deletedByMemberId?: NullableStringFieldUpdateOperationsInput | string | null topic?: TopicUpdateOneRequiredWithoutPostsNestedInput + reactions?: PostReactionUpdateManyWithoutPostNestedInput } export type PostUncheckedUpdateInput = { @@ -10228,6 +11547,7 @@ export namespace Prisma { updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string deletedAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null deletedByMemberId?: NullableStringFieldUpdateOperationsInput | string | null + reactions?: PostReactionUncheckedUpdateManyWithoutPostNestedInput } export type PostCreateManyInput = { @@ -10271,6 +11591,61 @@ export namespace Prisma { deletedByMemberId?: NullableStringFieldUpdateOperationsInput | string | null } + export type PostReactionCreateInput = { + memberId: string + reaction: $Enums.PostReactionType + createdAt?: Date | string + updatedAt?: Date | string + post: PostCreateNestedOneWithoutReactionsInput + } + + export type PostReactionUncheckedCreateInput = { + postId: string + memberId: string + reaction: $Enums.PostReactionType + createdAt?: Date | string + updatedAt?: Date | string + } + + export type PostReactionUpdateInput = { + memberId?: StringFieldUpdateOperationsInput | string + reaction?: EnumPostReactionTypeFieldUpdateOperationsInput | $Enums.PostReactionType + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + post?: PostUpdateOneRequiredWithoutReactionsNestedInput + } + + export type PostReactionUncheckedUpdateInput = { + postId?: StringFieldUpdateOperationsInput | string + memberId?: StringFieldUpdateOperationsInput | string + reaction?: EnumPostReactionTypeFieldUpdateOperationsInput | $Enums.PostReactionType + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + } + + export type PostReactionCreateManyInput = { + postId: string + memberId: string + reaction: $Enums.PostReactionType + createdAt?: Date | string + updatedAt?: Date | string + } + + export type PostReactionUpdateManyMutationInput = { + memberId?: StringFieldUpdateOperationsInput | string + reaction?: EnumPostReactionTypeFieldUpdateOperationsInput | $Enums.PostReactionType + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + } + + export type PostReactionUncheckedUpdateManyInput = { + postId?: StringFieldUpdateOperationsInput | string + memberId?: StringFieldUpdateOperationsInput | string + reaction?: EnumPostReactionTypeFieldUpdateOperationsInput | $Enums.PostReactionType + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + } + export type TopicClosureCreateInput = { depth: number ancestorTopic: TopicCreateNestedOneWithoutAncestorClosuresInput @@ -10702,6 +12077,16 @@ export namespace Prisma { isNot?: TopicWhereInput } + export type PostReactionListRelationFilter = { + every?: PostReactionWhereInput + some?: PostReactionWhereInput + none?: PostReactionWhereInput + } + + export type PostReactionOrderByRelationAggregateInput = { + _count?: SortOrder + } + export type PostCountOrderByAggregateInput = { id?: SortOrder topicId?: SortOrder @@ -10744,6 +12129,57 @@ export namespace Prisma { deletedByMemberId?: SortOrder } + export type EnumPostReactionTypeFilter<$PrismaModel = never> = { + equals?: $Enums.PostReactionType | EnumPostReactionTypeFieldRefInput<$PrismaModel> + in?: $Enums.PostReactionType[] | ListEnumPostReactionTypeFieldRefInput<$PrismaModel> + notIn?: $Enums.PostReactionType[] | ListEnumPostReactionTypeFieldRefInput<$PrismaModel> + not?: NestedEnumPostReactionTypeFilter<$PrismaModel> | $Enums.PostReactionType + } + + export type PostScalarRelationFilter = { + is?: PostWhereInput + isNot?: PostWhereInput + } + + export type PostReactionPostIdMemberIdCompoundUniqueInput = { + postId: string + memberId: string + } + + export type PostReactionCountOrderByAggregateInput = { + postId?: SortOrder + memberId?: SortOrder + reaction?: SortOrder + createdAt?: SortOrder + updatedAt?: SortOrder + } + + export type PostReactionMaxOrderByAggregateInput = { + postId?: SortOrder + memberId?: SortOrder + reaction?: SortOrder + createdAt?: SortOrder + updatedAt?: SortOrder + } + + export type PostReactionMinOrderByAggregateInput = { + postId?: SortOrder + memberId?: SortOrder + reaction?: SortOrder + createdAt?: SortOrder + updatedAt?: SortOrder + } + + export type EnumPostReactionTypeWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.PostReactionType | EnumPostReactionTypeFieldRefInput<$PrismaModel> + in?: $Enums.PostReactionType[] | ListEnumPostReactionTypeFieldRefInput<$PrismaModel> + notIn?: $Enums.PostReactionType[] | ListEnumPostReactionTypeFieldRefInput<$PrismaModel> + not?: NestedEnumPostReactionTypeWithAggregatesFilter<$PrismaModel> | $Enums.PostReactionType + _count?: NestedIntFilter<$PrismaModel> + _min?: NestedEnumPostReactionTypeFilter<$PrismaModel> + _max?: NestedEnumPostReactionTypeFilter<$PrismaModel> + } + export type IntFilter<$PrismaModel = never> = { equals?: number | IntFieldRefInput<$PrismaModel> in?: number[] | ListIntFieldRefInput<$PrismaModel> @@ -11145,6 +12581,20 @@ export namespace Prisma { connect?: TopicWhereUniqueInput } + export type PostReactionCreateNestedManyWithoutPostInput = { + create?: XOR | PostReactionCreateWithoutPostInput[] | PostReactionUncheckedCreateWithoutPostInput[] + connectOrCreate?: PostReactionCreateOrConnectWithoutPostInput | PostReactionCreateOrConnectWithoutPostInput[] + createMany?: PostReactionCreateManyPostInputEnvelope + connect?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + } + + export type PostReactionUncheckedCreateNestedManyWithoutPostInput = { + create?: XOR | PostReactionCreateWithoutPostInput[] | PostReactionUncheckedCreateWithoutPostInput[] + connectOrCreate?: PostReactionCreateOrConnectWithoutPostInput | PostReactionCreateOrConnectWithoutPostInput[] + createMany?: PostReactionCreateManyPostInputEnvelope + connect?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + } + export type TopicUpdateOneRequiredWithoutPostsNestedInput = { create?: XOR connectOrCreate?: TopicCreateOrConnectWithoutPostsInput @@ -11153,6 +12603,52 @@ export namespace Prisma { update?: XOR, TopicUncheckedUpdateWithoutPostsInput> } + export type PostReactionUpdateManyWithoutPostNestedInput = { + create?: XOR | PostReactionCreateWithoutPostInput[] | PostReactionUncheckedCreateWithoutPostInput[] + connectOrCreate?: PostReactionCreateOrConnectWithoutPostInput | PostReactionCreateOrConnectWithoutPostInput[] + upsert?: PostReactionUpsertWithWhereUniqueWithoutPostInput | PostReactionUpsertWithWhereUniqueWithoutPostInput[] + createMany?: PostReactionCreateManyPostInputEnvelope + set?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + disconnect?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + delete?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + connect?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + update?: PostReactionUpdateWithWhereUniqueWithoutPostInput | PostReactionUpdateWithWhereUniqueWithoutPostInput[] + updateMany?: PostReactionUpdateManyWithWhereWithoutPostInput | PostReactionUpdateManyWithWhereWithoutPostInput[] + deleteMany?: PostReactionScalarWhereInput | PostReactionScalarWhereInput[] + } + + export type PostReactionUncheckedUpdateManyWithoutPostNestedInput = { + create?: XOR | PostReactionCreateWithoutPostInput[] | PostReactionUncheckedCreateWithoutPostInput[] + connectOrCreate?: PostReactionCreateOrConnectWithoutPostInput | PostReactionCreateOrConnectWithoutPostInput[] + upsert?: PostReactionUpsertWithWhereUniqueWithoutPostInput | PostReactionUpsertWithWhereUniqueWithoutPostInput[] + createMany?: PostReactionCreateManyPostInputEnvelope + set?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + disconnect?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + delete?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + connect?: PostReactionWhereUniqueInput | PostReactionWhereUniqueInput[] + update?: PostReactionUpdateWithWhereUniqueWithoutPostInput | PostReactionUpdateWithWhereUniqueWithoutPostInput[] + updateMany?: PostReactionUpdateManyWithWhereWithoutPostInput | PostReactionUpdateManyWithWhereWithoutPostInput[] + deleteMany?: PostReactionScalarWhereInput | PostReactionScalarWhereInput[] + } + + export type PostCreateNestedOneWithoutReactionsInput = { + create?: XOR + connectOrCreate?: PostCreateOrConnectWithoutReactionsInput + connect?: PostWhereUniqueInput + } + + export type EnumPostReactionTypeFieldUpdateOperationsInput = { + set?: $Enums.PostReactionType + } + + export type PostUpdateOneRequiredWithoutReactionsNestedInput = { + create?: XOR + connectOrCreate?: PostCreateOrConnectWithoutReactionsInput + upsert?: PostUpsertWithoutReactionsInput + connect?: PostWhereUniqueInput + update?: XOR, PostUncheckedUpdateWithoutReactionsInput> + } + export type TopicCreateNestedOneWithoutAncestorClosuresInput = { create?: XOR connectOrCreate?: TopicCreateOrConnectWithoutAncestorClosuresInput @@ -11364,6 +12860,23 @@ export namespace Prisma { _max?: NestedDateTimeFilter<$PrismaModel> } + export type NestedEnumPostReactionTypeFilter<$PrismaModel = never> = { + equals?: $Enums.PostReactionType | EnumPostReactionTypeFieldRefInput<$PrismaModel> + in?: $Enums.PostReactionType[] | ListEnumPostReactionTypeFieldRefInput<$PrismaModel> + notIn?: $Enums.PostReactionType[] | ListEnumPostReactionTypeFieldRefInput<$PrismaModel> + not?: NestedEnumPostReactionTypeFilter<$PrismaModel> | $Enums.PostReactionType + } + + export type NestedEnumPostReactionTypeWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.PostReactionType | EnumPostReactionTypeFieldRefInput<$PrismaModel> + in?: $Enums.PostReactionType[] | ListEnumPostReactionTypeFieldRefInput<$PrismaModel> + notIn?: $Enums.PostReactionType[] | ListEnumPostReactionTypeFieldRefInput<$PrismaModel> + not?: NestedEnumPostReactionTypeWithAggregatesFilter<$PrismaModel> | $Enums.PostReactionType + _count?: NestedIntFilter<$PrismaModel> + _min?: NestedEnumPostReactionTypeFilter<$PrismaModel> + _max?: NestedEnumPostReactionTypeFilter<$PrismaModel> + } + export type NestedIntWithAggregatesFilter<$PrismaModel = never> = { equals?: number | IntFieldRefInput<$PrismaModel> in?: number[] | ListIntFieldRefInput<$PrismaModel> @@ -11509,6 +13022,7 @@ export namespace Prisma { updatedAt?: Date | string deletedAt?: Date | string | null deletedByMemberId?: string | null + reactions?: PostReactionCreateNestedManyWithoutPostInput } export type PostUncheckedCreateWithoutTopicInput = { @@ -11522,6 +13036,7 @@ export namespace Prisma { updatedAt?: Date | string deletedAt?: Date | string | null deletedByMemberId?: string | null + reactions?: PostReactionUncheckedCreateNestedManyWithoutPostInput } export type PostCreateOrConnectWithoutTopicInput = { @@ -11886,6 +13401,30 @@ export namespace Prisma { create: XOR } + export type PostReactionCreateWithoutPostInput = { + memberId: string + reaction: $Enums.PostReactionType + createdAt?: Date | string + updatedAt?: Date | string + } + + export type PostReactionUncheckedCreateWithoutPostInput = { + memberId: string + reaction: $Enums.PostReactionType + createdAt?: Date | string + updatedAt?: Date | string + } + + export type PostReactionCreateOrConnectWithoutPostInput = { + where: PostReactionWhereUniqueInput + create: XOR + } + + export type PostReactionCreateManyPostInputEnvelope = { + data: PostReactionCreateManyPostInput | PostReactionCreateManyPostInput[] + skipDuplicates?: boolean + } + export type TopicUpsertWithoutPostsInput = { update: XOR create: XOR @@ -11943,6 +13482,105 @@ export namespace Prisma { readStates?: TopicReadStateUncheckedUpdateManyWithoutTopicNestedInput } + export type PostReactionUpsertWithWhereUniqueWithoutPostInput = { + where: PostReactionWhereUniqueInput + update: XOR + create: XOR + } + + export type PostReactionUpdateWithWhereUniqueWithoutPostInput = { + where: PostReactionWhereUniqueInput + data: XOR + } + + export type PostReactionUpdateManyWithWhereWithoutPostInput = { + where: PostReactionScalarWhereInput + data: XOR + } + + export type PostReactionScalarWhereInput = { + AND?: PostReactionScalarWhereInput | PostReactionScalarWhereInput[] + OR?: PostReactionScalarWhereInput[] + NOT?: PostReactionScalarWhereInput | PostReactionScalarWhereInput[] + postId?: StringFilter<"PostReaction"> | string + memberId?: StringFilter<"PostReaction"> | string + reaction?: EnumPostReactionTypeFilter<"PostReaction"> | $Enums.PostReactionType + createdAt?: DateTimeFilter<"PostReaction"> | Date | string + updatedAt?: DateTimeFilter<"PostReaction"> | Date | string + } + + export type PostCreateWithoutReactionsInput = { + id?: string + parentType: string + parentId: string + authorMemberId: string + authorHandle: string + content?: string | null + createdAt?: Date | string + updatedAt?: Date | string + deletedAt?: Date | string | null + deletedByMemberId?: string | null + topic: TopicCreateNestedOneWithoutPostsInput + } + + export type PostUncheckedCreateWithoutReactionsInput = { + id?: string + topicId: string + parentType: string + parentId: string + authorMemberId: string + authorHandle: string + content?: string | null + createdAt?: Date | string + updatedAt?: Date | string + deletedAt?: Date | string | null + deletedByMemberId?: string | null + } + + export type PostCreateOrConnectWithoutReactionsInput = { + where: PostWhereUniqueInput + create: XOR + } + + export type PostUpsertWithoutReactionsInput = { + update: XOR + create: XOR + where?: PostWhereInput + } + + export type PostUpdateToOneWithWhereWithoutReactionsInput = { + where?: PostWhereInput + data: XOR + } + + export type PostUpdateWithoutReactionsInput = { + id?: StringFieldUpdateOperationsInput | string + parentType?: StringFieldUpdateOperationsInput | string + parentId?: StringFieldUpdateOperationsInput | string + authorMemberId?: StringFieldUpdateOperationsInput | string + authorHandle?: StringFieldUpdateOperationsInput | string + content?: NullableStringFieldUpdateOperationsInput | string | null + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null + deletedByMemberId?: NullableStringFieldUpdateOperationsInput | string | null + topic?: TopicUpdateOneRequiredWithoutPostsNestedInput + } + + export type PostUncheckedUpdateWithoutReactionsInput = { + id?: StringFieldUpdateOperationsInput | string + topicId?: StringFieldUpdateOperationsInput | string + parentType?: StringFieldUpdateOperationsInput | string + parentId?: StringFieldUpdateOperationsInput | string + authorMemberId?: StringFieldUpdateOperationsInput | string + authorHandle?: StringFieldUpdateOperationsInput | string + content?: NullableStringFieldUpdateOperationsInput | string | null + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + deletedAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null + deletedByMemberId?: NullableStringFieldUpdateOperationsInput | string | null + } + export type TopicCreateWithoutAncestorClosuresInput = { id?: string challengeId?: string | null @@ -12500,6 +14138,7 @@ export namespace Prisma { updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string deletedAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null deletedByMemberId?: NullableStringFieldUpdateOperationsInput | string | null + reactions?: PostReactionUpdateManyWithoutPostNestedInput } export type PostUncheckedUpdateWithoutTopicInput = { @@ -12513,6 +14152,7 @@ export namespace Prisma { updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string deletedAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null deletedByMemberId?: NullableStringFieldUpdateOperationsInput | string | null + reactions?: PostReactionUncheckedUpdateManyWithoutPostNestedInput } export type PostUncheckedUpdateManyWithoutTopicInput = { @@ -12591,6 +14231,34 @@ export namespace Prisma { updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string } + export type PostReactionCreateManyPostInput = { + memberId: string + reaction: $Enums.PostReactionType + createdAt?: Date | string + updatedAt?: Date | string + } + + export type PostReactionUpdateWithoutPostInput = { + memberId?: StringFieldUpdateOperationsInput | string + reaction?: EnumPostReactionTypeFieldUpdateOperationsInput | $Enums.PostReactionType + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + } + + export type PostReactionUncheckedUpdateWithoutPostInput = { + memberId?: StringFieldUpdateOperationsInput | string + reaction?: EnumPostReactionTypeFieldUpdateOperationsInput | $Enums.PostReactionType + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + } + + export type PostReactionUncheckedUpdateManyWithoutPostInput = { + memberId?: StringFieldUpdateOperationsInput | string + reaction?: EnumPostReactionTypeFieldUpdateOperationsInput | $Enums.PostReactionType + createdAt?: DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string + } + /** diff --git a/packages/forums-prisma-client/index.js b/packages/forums-prisma-client/index.js index 135464a..73cb996 100644 --- a/packages/forums-prisma-client/index.js +++ b/packages/forums-prisma-client/index.js @@ -143,6 +143,14 @@ exports.Prisma.PostScalarFieldEnum = { deletedByMemberId: 'deletedByMemberId' }; +exports.Prisma.PostReactionScalarFieldEnum = { + postId: 'postId', + memberId: 'memberId', + reaction: 'reaction', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +}; + exports.Prisma.TopicClosureScalarFieldEnum = { ancestorTopicId: 'ancestorTopicId', descendantTopicId: 'descendantTopicId', @@ -176,13 +184,17 @@ exports.Prisma.NullsOrder = { first: 'first', last: 'last' }; - +exports.PostReactionType = exports.$Enums.PostReactionType = { + THUMBS_UP: 'THUMBS_UP', + THUMBS_DOWN: 'THUMBS_DOWN' +}; exports.Prisma.ModelName = { Topic: 'Topic', MemberBan: 'MemberBan', IpBan: 'IpBan', Post: 'Post', + PostReaction: 'PostReaction', TopicClosure: 'TopicClosure', TopicWatch: 'TopicWatch', TopicReadState: 'TopicReadState' @@ -195,14 +207,14 @@ const config = { "clientVersion": "7.9.0", "engineVersion": "e922089b7d7502aff4249d5da3420f6fa55fc6ad", "activeProvider": "postgresql", - "inlineSchema": "generator client {\n provider = \"prisma-client-js\"\n output = \"./generated/client\"\n}\n\ngenerator externalClient {\n provider = \"prisma-client-js\"\n output = \"../packages/forums-prisma-client\"\n binaryTargets = [\"native\", \"debian-openssl-3.0.x\"]\n}\n\ndatasource db {\n provider = \"postgresql\"\n schemas = [\"forums\"]\n}\n\nmodel Topic {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n parentTopicId String? @db.VarChar(14)\n challengeId String? @db.VarChar(64)\n roleName String? @db.VarChar(128)\n title String @db.VarChar(255)\n isAnnouncement Boolean @default(false)\n locked Boolean @default(false)\n lockedAt DateTime?\n lockedByMemberId String? @db.VarChar(64)\n authorMemberId String @db.VarChar(64)\n authorHandle String @db.VarChar(128)\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n deletedAt DateTime?\n deletedByMemberId String? @db.VarChar(64)\n\n parentTopic Topic? @relation(\"TopicChildren\", fields: [parentTopicId], references: [id])\n childTopics Topic[] @relation(\"TopicChildren\")\n posts Post[]\n ancestorClosures TopicClosure[] @relation(\"TopicClosureAncestor\")\n descendantClosures TopicClosure[] @relation(\"TopicClosureDescendant\")\n watches TopicWatch[]\n readStates TopicReadState[]\n\n @@index([parentTopicId])\n @@index([challengeId])\n @@index([roleName])\n @@index([deletedAt])\n @@index([isAnnouncement, createdAt])\n @@schema(\"forums\")\n}\n\nmodel MemberBan {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n memberId String @db.VarChar(64)\n createdAt DateTime @default(now())\n createdByMemberId String? @db.VarChar(64)\n removedAt DateTime?\n removedByMemberId String? @db.VarChar(64)\n\n @@index([memberId])\n @@index([removedAt])\n @@schema(\"forums\")\n}\n\nmodel IpBan {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n ipAddress String @db.VarChar(45)\n createdAt DateTime @default(now())\n createdByMemberId String? @db.VarChar(64)\n removedAt DateTime?\n removedByMemberId String? @db.VarChar(64)\n\n @@index([ipAddress])\n @@index([removedAt])\n @@schema(\"forums\")\n}\n\nmodel Post {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n topicId String @db.VarChar(14)\n parentType String @db.VarChar(16)\n parentId String @db.VarChar(14)\n authorMemberId String @db.VarChar(64)\n authorHandle String @db.VarChar(128)\n content String? @db.Text\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n deletedAt DateTime?\n deletedByMemberId String? @db.VarChar(64)\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@index([topicId, createdAt])\n @@index([topicId, parentType, parentId])\n @@index([deletedAt])\n @@schema(\"forums\")\n}\n\nmodel TopicClosure {\n ancestorTopicId String @db.VarChar(14)\n descendantTopicId String @db.VarChar(14)\n depth Int\n\n ancestorTopic Topic @relation(\"TopicClosureAncestor\", fields: [ancestorTopicId], references: [id], onDelete: Cascade)\n descendantTopic Topic @relation(\"TopicClosureDescendant\", fields: [descendantTopicId], references: [id], onDelete: Cascade)\n\n @@id([ancestorTopicId, descendantTopicId])\n @@index([ancestorTopicId, depth])\n @@index([descendantTopicId, depth])\n @@schema(\"forums\")\n}\n\nmodel TopicWatch {\n topicId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n createdAt DateTime @default(now())\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@id([topicId, memberId])\n @@index([memberId])\n @@schema(\"forums\")\n}\n\nmodel TopicReadState {\n topicId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n lastReadAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@id([topicId, memberId])\n @@index([memberId])\n @@index([lastReadAt])\n @@schema(\"forums\")\n}\n" + "inlineSchema": "generator client {\n provider = \"prisma-client-js\"\n output = \"./generated/client\"\n}\n\ngenerator externalClient {\n provider = \"prisma-client-js\"\n output = \"../packages/forums-prisma-client\"\n binaryTargets = [\"native\", \"debian-openssl-3.0.x\"]\n}\n\ndatasource db {\n provider = \"postgresql\"\n schemas = [\"forums\"]\n}\n\nenum PostReactionType {\n THUMBS_UP\n THUMBS_DOWN\n\n @@schema(\"forums\")\n}\n\nmodel Topic {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n parentTopicId String? @db.VarChar(14)\n challengeId String? @db.VarChar(64)\n roleName String? @db.VarChar(128)\n title String @db.VarChar(255)\n isAnnouncement Boolean @default(false)\n locked Boolean @default(false)\n lockedAt DateTime?\n lockedByMemberId String? @db.VarChar(64)\n authorMemberId String @db.VarChar(64)\n authorHandle String @db.VarChar(128)\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n deletedAt DateTime?\n deletedByMemberId String? @db.VarChar(64)\n\n parentTopic Topic? @relation(\"TopicChildren\", fields: [parentTopicId], references: [id])\n childTopics Topic[] @relation(\"TopicChildren\")\n posts Post[]\n ancestorClosures TopicClosure[] @relation(\"TopicClosureAncestor\")\n descendantClosures TopicClosure[] @relation(\"TopicClosureDescendant\")\n watches TopicWatch[]\n readStates TopicReadState[]\n\n @@index([parentTopicId])\n @@index([challengeId])\n @@index([roleName])\n @@index([deletedAt])\n @@index([isAnnouncement, createdAt])\n @@schema(\"forums\")\n}\n\nmodel MemberBan {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n memberId String @db.VarChar(64)\n createdAt DateTime @default(now())\n createdByMemberId String? @db.VarChar(64)\n removedAt DateTime?\n removedByMemberId String? @db.VarChar(64)\n\n @@index([memberId])\n @@index([removedAt])\n @@schema(\"forums\")\n}\n\nmodel IpBan {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n ipAddress String @db.VarChar(45)\n createdAt DateTime @default(now())\n createdByMemberId String? @db.VarChar(64)\n removedAt DateTime?\n removedByMemberId String? @db.VarChar(64)\n\n @@index([ipAddress])\n @@index([removedAt])\n @@schema(\"forums\")\n}\n\nmodel Post {\n id String @id @default(dbgenerated(\"nanoid()\")) @db.VarChar(14)\n topicId String @db.VarChar(14)\n parentType String @db.VarChar(16)\n parentId String @db.VarChar(14)\n authorMemberId String @db.VarChar(64)\n authorHandle String @db.VarChar(128)\n content String? @db.Text\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n deletedAt DateTime?\n deletedByMemberId String? @db.VarChar(64)\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n reactions PostReaction[]\n\n @@index([topicId, createdAt])\n @@index([topicId, parentType, parentId])\n @@index([deletedAt])\n @@schema(\"forums\")\n}\n\nmodel PostReaction {\n postId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n reaction PostReactionType\n createdAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n\n post Post @relation(fields: [postId], references: [id], onDelete: Cascade)\n\n @@id([postId, memberId])\n @@index([memberId])\n @@index([postId, reaction])\n @@schema(\"forums\")\n}\n\nmodel TopicClosure {\n ancestorTopicId String @db.VarChar(14)\n descendantTopicId String @db.VarChar(14)\n depth Int\n\n ancestorTopic Topic @relation(\"TopicClosureAncestor\", fields: [ancestorTopicId], references: [id], onDelete: Cascade)\n descendantTopic Topic @relation(\"TopicClosureDescendant\", fields: [descendantTopicId], references: [id], onDelete: Cascade)\n\n @@id([ancestorTopicId, descendantTopicId])\n @@index([ancestorTopicId, depth])\n @@index([descendantTopicId, depth])\n @@schema(\"forums\")\n}\n\nmodel TopicWatch {\n topicId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n createdAt DateTime @default(now())\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@id([topicId, memberId])\n @@index([memberId])\n @@schema(\"forums\")\n}\n\nmodel TopicReadState {\n topicId String @db.VarChar(14)\n memberId String @db.VarChar(64)\n lastReadAt DateTime @default(now())\n updatedAt DateTime @default(now()) @updatedAt\n\n topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade)\n\n @@id([topicId, memberId])\n @@index([memberId])\n @@index([lastReadAt])\n @@schema(\"forums\")\n}\n" } -config.runtimeDataModel = JSON.parse("{\"models\":{\"Topic\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengeId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roleName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isAnnouncement\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"locked\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"lockedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"lockedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorHandle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicChildren\"},{\"name\":\"childTopics\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicChildren\"},{\"name\":\"posts\",\"kind\":\"object\",\"type\":\"Post\",\"relationName\":\"PostToTopic\"},{\"name\":\"ancestorClosures\",\"kind\":\"object\",\"type\":\"TopicClosure\",\"relationName\":\"TopicClosureAncestor\"},{\"name\":\"descendantClosures\",\"kind\":\"object\",\"type\":\"TopicClosure\",\"relationName\":\"TopicClosureDescendant\"},{\"name\":\"watches\",\"kind\":\"object\",\"type\":\"TopicWatch\",\"relationName\":\"TopicToTopicWatch\"},{\"name\":\"readStates\",\"kind\":\"object\",\"type\":\"TopicReadState\",\"relationName\":\"TopicToTopicReadState\"}],\"dbName\":null},\"MemberBan\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"removedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"removedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"IpBan\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"ipAddress\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"removedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"removedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"Post\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorHandle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"PostToTopic\"}],\"dbName\":null},\"TopicClosure\":{\"fields\":[{\"name\":\"ancestorTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"descendantTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"depth\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"ancestorTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicClosureAncestor\"},{\"name\":\"descendantTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicClosureDescendant\"}],\"dbName\":null},\"TopicWatch\":{\"fields\":[{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicToTopicWatch\"}],\"dbName\":null},\"TopicReadState\":{\"fields\":[{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"lastReadAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicToTopicReadState\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"Topic\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"challengeId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"roleName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isAnnouncement\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"locked\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"lockedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"lockedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorHandle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicChildren\"},{\"name\":\"childTopics\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicChildren\"},{\"name\":\"posts\",\"kind\":\"object\",\"type\":\"Post\",\"relationName\":\"PostToTopic\"},{\"name\":\"ancestorClosures\",\"kind\":\"object\",\"type\":\"TopicClosure\",\"relationName\":\"TopicClosureAncestor\"},{\"name\":\"descendantClosures\",\"kind\":\"object\",\"type\":\"TopicClosure\",\"relationName\":\"TopicClosureDescendant\"},{\"name\":\"watches\",\"kind\":\"object\",\"type\":\"TopicWatch\",\"relationName\":\"TopicToTopicWatch\"},{\"name\":\"readStates\",\"kind\":\"object\",\"type\":\"TopicReadState\",\"relationName\":\"TopicToTopicReadState\"}],\"dbName\":null},\"MemberBan\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"removedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"removedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"IpBan\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"ipAddress\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"removedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"removedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null},\"Post\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"parentId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"authorHandle\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"content\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deletedByMemberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"PostToTopic\"},{\"name\":\"reactions\",\"kind\":\"object\",\"type\":\"PostReaction\",\"relationName\":\"PostToPostReaction\"}],\"dbName\":null},\"PostReaction\":{\"fields\":[{\"name\":\"postId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"reaction\",\"kind\":\"enum\",\"type\":\"PostReactionType\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"post\",\"kind\":\"object\",\"type\":\"Post\",\"relationName\":\"PostToPostReaction\"}],\"dbName\":null},\"TopicClosure\":{\"fields\":[{\"name\":\"ancestorTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"descendantTopicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"depth\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"ancestorTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicClosureAncestor\"},{\"name\":\"descendantTopic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicClosureDescendant\"}],\"dbName\":null},\"TopicWatch\":{\"fields\":[{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicToTopicWatch\"}],\"dbName\":null},\"TopicReadState\":{\"fields\":[{\"name\":\"topicId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"memberId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"lastReadAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"topic\",\"kind\":\"object\",\"type\":\"Topic\",\"relationName\":\"TopicToTopicReadState\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") defineDmmfProperty(exports.Prisma, config.runtimeDataModel) config.parameterizationSchema = { - strings: JSON.parse("[\"where\",\"parentTopic\",\"orderBy\",\"cursor\",\"childTopics\",\"topic\",\"posts\",\"ancestorTopic\",\"descendantTopic\",\"ancestorClosures\",\"descendantClosures\",\"watches\",\"readStates\",\"_count\",\"Topic.findUnique\",\"Topic.findUniqueOrThrow\",\"Topic.findFirst\",\"Topic.findFirstOrThrow\",\"Topic.findMany\",\"data\",\"Topic.createOne\",\"Topic.createMany\",\"Topic.createManyAndReturn\",\"Topic.updateOne\",\"Topic.updateMany\",\"Topic.updateManyAndReturn\",\"create\",\"update\",\"Topic.upsertOne\",\"Topic.deleteOne\",\"Topic.deleteMany\",\"having\",\"_min\",\"_max\",\"Topic.groupBy\",\"Topic.aggregate\",\"MemberBan.findUnique\",\"MemberBan.findUniqueOrThrow\",\"MemberBan.findFirst\",\"MemberBan.findFirstOrThrow\",\"MemberBan.findMany\",\"MemberBan.createOne\",\"MemberBan.createMany\",\"MemberBan.createManyAndReturn\",\"MemberBan.updateOne\",\"MemberBan.updateMany\",\"MemberBan.updateManyAndReturn\",\"MemberBan.upsertOne\",\"MemberBan.deleteOne\",\"MemberBan.deleteMany\",\"MemberBan.groupBy\",\"MemberBan.aggregate\",\"IpBan.findUnique\",\"IpBan.findUniqueOrThrow\",\"IpBan.findFirst\",\"IpBan.findFirstOrThrow\",\"IpBan.findMany\",\"IpBan.createOne\",\"IpBan.createMany\",\"IpBan.createManyAndReturn\",\"IpBan.updateOne\",\"IpBan.updateMany\",\"IpBan.updateManyAndReturn\",\"IpBan.upsertOne\",\"IpBan.deleteOne\",\"IpBan.deleteMany\",\"IpBan.groupBy\",\"IpBan.aggregate\",\"Post.findUnique\",\"Post.findUniqueOrThrow\",\"Post.findFirst\",\"Post.findFirstOrThrow\",\"Post.findMany\",\"Post.createOne\",\"Post.createMany\",\"Post.createManyAndReturn\",\"Post.updateOne\",\"Post.updateMany\",\"Post.updateManyAndReturn\",\"Post.upsertOne\",\"Post.deleteOne\",\"Post.deleteMany\",\"Post.groupBy\",\"Post.aggregate\",\"TopicClosure.findUnique\",\"TopicClosure.findUniqueOrThrow\",\"TopicClosure.findFirst\",\"TopicClosure.findFirstOrThrow\",\"TopicClosure.findMany\",\"TopicClosure.createOne\",\"TopicClosure.createMany\",\"TopicClosure.createManyAndReturn\",\"TopicClosure.updateOne\",\"TopicClosure.updateMany\",\"TopicClosure.updateManyAndReturn\",\"TopicClosure.upsertOne\",\"TopicClosure.deleteOne\",\"TopicClosure.deleteMany\",\"_avg\",\"_sum\",\"TopicClosure.groupBy\",\"TopicClosure.aggregate\",\"TopicWatch.findUnique\",\"TopicWatch.findUniqueOrThrow\",\"TopicWatch.findFirst\",\"TopicWatch.findFirstOrThrow\",\"TopicWatch.findMany\",\"TopicWatch.createOne\",\"TopicWatch.createMany\",\"TopicWatch.createManyAndReturn\",\"TopicWatch.updateOne\",\"TopicWatch.updateMany\",\"TopicWatch.updateManyAndReturn\",\"TopicWatch.upsertOne\",\"TopicWatch.deleteOne\",\"TopicWatch.deleteMany\",\"TopicWatch.groupBy\",\"TopicWatch.aggregate\",\"TopicReadState.findUnique\",\"TopicReadState.findUniqueOrThrow\",\"TopicReadState.findFirst\",\"TopicReadState.findFirstOrThrow\",\"TopicReadState.findMany\",\"TopicReadState.createOne\",\"TopicReadState.createMany\",\"TopicReadState.createManyAndReturn\",\"TopicReadState.updateOne\",\"TopicReadState.updateMany\",\"TopicReadState.updateManyAndReturn\",\"TopicReadState.upsertOne\",\"TopicReadState.deleteOne\",\"TopicReadState.deleteMany\",\"TopicReadState.groupBy\",\"TopicReadState.aggregate\",\"AND\",\"OR\",\"NOT\",\"topicId\",\"memberId\",\"lastReadAt\",\"updatedAt\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"not\",\"contains\",\"startsWith\",\"endsWith\",\"createdAt\",\"ancestorTopicId\",\"descendantTopicId\",\"depth\",\"id\",\"parentType\",\"parentId\",\"authorMemberId\",\"authorHandle\",\"content\",\"deletedAt\",\"deletedByMemberId\",\"ipAddress\",\"createdByMemberId\",\"removedAt\",\"removedByMemberId\",\"parentTopicId\",\"challengeId\",\"roleName\",\"title\",\"isAnnouncement\",\"locked\",\"lockedAt\",\"lockedByMemberId\",\"topicId_memberId\",\"ancestorTopicId_descendantTopicId\",\"every\",\"some\",\"none\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"), - graph: "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_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_AEAIIkBAQAAAAGKAQEAAAABmAFAAAAAAQETAACYAQAgA4kBAQAAAAGKAQEAAAABmAFAAAAAAQETAACaAQAwARMAAJoBADAEBQAA-wEAIIkBAQD0AQAhigEBAPQBACGYAUAA9QEAIQIAAAASACATAACdAQAgA4kBAQD0AQAhigEBAPQBACGYAUAA9QEAIQIAAAAQACATAACfAQAgAgAAABAAIBMAAJ8BACADAAAAEgAgGgAAmAEAIBsAAJ0BACABAAAAEgAgAQAAABAAIAMNAAD4AQAgIAAA-gEAICEAAPkBACAGhgEAAMcBADCHAQAApgEAEIgBAADHAQAwiQEBAMABACGKAQEAwAEAIZgBQADBAQAhAwAAABAAIAIAAKUBADAfAACmAQAgAwAAABAAIAIAABEAMAMAABIAIAEAAAAWACABAAAAFgAgAwAAABQAIAIAABUAMAMAABYAIAMAAAAUACACAAAVADADAAAWACADAAAAFAAgAgAAFQAwAwAAFgAgBQUAAPcBACCJAQEAAAABigEBAAAAAYsBQAAAAAGMAUAAAAABARMAAK4BACAEiQEBAAAAAYoBAQAAAAGLAUAAAAABjAFAAAAAAQETAACwAQAwARMAALABADAFBQAA9gEAIIkBAQD0AQAhigEBAPQBACGLAUAA9QEAIYwBQAD1AQAhAgAAABYAIBMAALMBACAEiQEBAPQBACGKAQEA9AEAIYsBQAD1AQAhjAFAAPUBACECAAAAFAAgEwAAtQEAIAIAAAAUACATAAC1AQAgAwAAABYAIBoAAK4BACAbAACzAQAgAQAAABYAIAEAAAAUACADDQAA8QEAICAAAPMBACAhAADyAQAgB4YBAAC_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_wIAIL0BAAABACADGgAA_QIAILcBAAD-AgAgvQEAAAEAIAAAAAAAAAAAAAG6ASAAAAABBxoAAPICACAbAAD7AgAgtwEAAPMCACC4AQAA-gIAILsBAAADACC8AQAAAwAgvQEAAAEAIAsaAADZAgAwGwAA3gIAMLcBAADaAgAwuAEAANsCADC5AQAA3AIAILoBAADdAgAwuwEAAN0CADC8AQAA3QIAML0BAADdAgAwvgEAAN8CADC_AQAA4AIAMAsaAADNAgAwGwAA0gIAMLcBAADOAgAwuAEAAM8CADC5AQAA0AIAILoBAADRAgAwuwEAANECADC8AQAA0QIAML0BAADRAgAwvgEAANMCADC_AQAA1AIAMAsaAADEAgAwGwAAyAIAMLcBAADFAgAwuAEAAMYCADC5AQAAxwIAILoBAAC8AgAwuwEAALwCADC8AQAAvAIAML0BAAC8AgAwvgEAAMkCADC_AQAAvwIAMAsaAAC4AgAwGwAAvQIAMLcBAAC5AgAwuAEAALoCADC5AQAAuwIAILoBAAC8AgAwuwEAALwCADC8AQAAvAIAML0BAAC8AgAwvgEAAL4CADC_AQAAvwIAMAsaAACsAgAwGwAAsQIAMLcBAACtAgAwuAEAAK4CADC5AQAArwIAILoBAACwAgAwuwEAALACADC8AQAAsAIAML0BAACwAgAwvgEAALICADC_AQAAswIAMAsaAACgAgAwGwAApQIAMLcBAAChAgAwuAEAAKICADC5AQAAowIAILoBAACkAgAwuwEAAKQCADC8AQAApAIAML0BAACkAgAwvgEAAKYCADC_AQAApwIAMAOKAQEAAAABiwFAAAAAAYwBQAAAAAECAAAAFgAgGgAAqwIAIAMAAAAWACAaAACrAgAgGwAAqgIAIAETAAD5AgAwCQUAAOIBACCGAQAA4QEAMIcBAAAUABCIAQAA4QEAMIkBAQDWAQAhigEBANYBACGLAUAA1wEAIYwBQADXAQAhsAEAAOABACACAAAAFgAgEwAAqgIAIAIAAACoAgAgEwAAqQIAIAeGAQAApwIAMIcBAACoAgAQiAEAAKcCADCJAQEA1gEAIYoBAQDWAQAhiwFAANcBACGMAUAA1wEAIQeGAQAApwIAMIcBAACoAgAQiAEAAKcCADCJAQEA1gEAIYoBAQDWAQAhiwFAANcBACGMAUAA1wEAIQOKAQEA9AEAIYsBQAD1AQAhjAFAAPUBACEDigEBAPQBACGLAUAA9QEAIYwBQAD1AQAhA4oBAQAAAAGLAUAAAAABjAFAAAAAAQKKAQEAAAABmAFAAAAAAQIAAAASACAaAAC3AgAgAwAAABIAIBoAALcCACAbAAC2AgAgARMAAPgCADAIBQAA4gEAIIYBAADkAQAwhwEAABAAEIgBAADkAQAwiQEBANYBACGKAQEA1gEAIZgBQADXAQAhsAEAAOMBACACAAAAEgAgEwAAtgIAIAIAAAC0AgAgEwAAtQIAIAaGAQAAswIAMIcBAAC0AgAQiAEAALMCADCJAQEA1gEAIYoBAQDWAQAhmAFAANcBACEGhgEAALMCADCHAQAAtAIAEIgBAACzAgAwiQEBANYBACGKAQEA1gEAIZgBQADXAQAhAooBAQD0AQAhmAFAAPUBACECigEBAPQBACGYAUAA9QEAIQKKAQEAAAABmAFAAAAAAQMHAACFAgAgmQEBAAAAAZsBAgAAAAECAAAADQAgGgAAwwIAIAMAAAANACAaAADDAgAgGwAAwgIAIAETAAD3AgAwCQcAAOIBACAIAADiAQAghgEAAOYBADCHAQAACwAQiAEAAOYBADCZAQEA1gEAIZoBAQDWAQAhmwECAOcBACGxAQAA5QEAIAIAAAANACATAADCAgAgAgAAAMACACATAADBAgAgBoYBAAC_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_AIAIIwBQAD1AQAhmAFAAPUBACGcAQEA9AEAIZ8BAQD0AQAhoAEBAPQBACGiAUAAjAIAIaMBAQCLAgAhqAEBAIsCACGpAQEAiwIAIaoBAQCLAgAhqwEBAPQBACGsASAAmAIAIa0BIACYAgAhrgFAAIwCACGvAQEAiwIAIRUBAACZAgAgBgAAmwIAIAkAAJwCACAKAACdAgAgCwAAngIAIAwAAJ8CACCMAUAA9QEAIZgBQAD1AQAhnAEBAPQBACGfAQEA9AEAIaABAQD0AQAhogFAAIwCACGjAQEAiwIAIagBAQCLAgAhqQEBAIsCACGqAQEAiwIAIasBAQD0AQAhrAEgAJgCACGtASAAmAIAIa4BQACMAgAhrwEBAIsCACEVAQAA6wIAIAQAAOUCACAJAADnAgAgCgAA6AIAIAsAAOkCACAMAADqAgAgjAFAAAAAAZgBQAAAAAGcAQEAAAABnwEBAAAAAaABAQAAAAGiAUAAAAABowEBAAAAAagBAQAAAAGpAQEAAAABqgEBAAAAAasBAQAAAAGsASAAAAABrQEgAAAAAa4BQAAAAAGvAQEAAAABAgAAAAEAIBoAAP0CACADAAAAAwAgGgAA_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-Xxk_YBdAYRdBYgdCZRpDZh5EZwJFaAJGaQJHagJIawJJbQJKbwdLcB9McgJNdAdOdSBPdgJQdwJReAdSeyFTfCVUfQNVfgNWfwNXgAEDWIEBA1mDAQNahQEHW4YBJlyIAQNdigEHXosBJ1-MAQNgjQEDYY4BB2SRAShlkgEuZpMBBGeUAQRolQEEaZYBBGqXAQRrmQEEbJsBB22cAS9ungEEb6ABB3ChATBxogEEcqMBBHOkAQd0pwExdagBNXapAQV3qgEFeKsBBXmsAQV6rQEFe68BBXyxAQd9sgE2frQBBX-2AQeAAbcBN4EBuAEFggG5AQWDAboBB4QBvQE4hQG-ATw" + strings: JSON.parse("[\"where\",\"parentTopic\",\"orderBy\",\"cursor\",\"childTopics\",\"topic\",\"post\",\"reactions\",\"_count\",\"posts\",\"ancestorTopic\",\"descendantTopic\",\"ancestorClosures\",\"descendantClosures\",\"watches\",\"readStates\",\"Topic.findUnique\",\"Topic.findUniqueOrThrow\",\"Topic.findFirst\",\"Topic.findFirstOrThrow\",\"Topic.findMany\",\"data\",\"Topic.createOne\",\"Topic.createMany\",\"Topic.createManyAndReturn\",\"Topic.updateOne\",\"Topic.updateMany\",\"Topic.updateManyAndReturn\",\"create\",\"update\",\"Topic.upsertOne\",\"Topic.deleteOne\",\"Topic.deleteMany\",\"having\",\"_min\",\"_max\",\"Topic.groupBy\",\"Topic.aggregate\",\"MemberBan.findUnique\",\"MemberBan.findUniqueOrThrow\",\"MemberBan.findFirst\",\"MemberBan.findFirstOrThrow\",\"MemberBan.findMany\",\"MemberBan.createOne\",\"MemberBan.createMany\",\"MemberBan.createManyAndReturn\",\"MemberBan.updateOne\",\"MemberBan.updateMany\",\"MemberBan.updateManyAndReturn\",\"MemberBan.upsertOne\",\"MemberBan.deleteOne\",\"MemberBan.deleteMany\",\"MemberBan.groupBy\",\"MemberBan.aggregate\",\"IpBan.findUnique\",\"IpBan.findUniqueOrThrow\",\"IpBan.findFirst\",\"IpBan.findFirstOrThrow\",\"IpBan.findMany\",\"IpBan.createOne\",\"IpBan.createMany\",\"IpBan.createManyAndReturn\",\"IpBan.updateOne\",\"IpBan.updateMany\",\"IpBan.updateManyAndReturn\",\"IpBan.upsertOne\",\"IpBan.deleteOne\",\"IpBan.deleteMany\",\"IpBan.groupBy\",\"IpBan.aggregate\",\"Post.findUnique\",\"Post.findUniqueOrThrow\",\"Post.findFirst\",\"Post.findFirstOrThrow\",\"Post.findMany\",\"Post.createOne\",\"Post.createMany\",\"Post.createManyAndReturn\",\"Post.updateOne\",\"Post.updateMany\",\"Post.updateManyAndReturn\",\"Post.upsertOne\",\"Post.deleteOne\",\"Post.deleteMany\",\"Post.groupBy\",\"Post.aggregate\",\"PostReaction.findUnique\",\"PostReaction.findUniqueOrThrow\",\"PostReaction.findFirst\",\"PostReaction.findFirstOrThrow\",\"PostReaction.findMany\",\"PostReaction.createOne\",\"PostReaction.createMany\",\"PostReaction.createManyAndReturn\",\"PostReaction.updateOne\",\"PostReaction.updateMany\",\"PostReaction.updateManyAndReturn\",\"PostReaction.upsertOne\",\"PostReaction.deleteOne\",\"PostReaction.deleteMany\",\"PostReaction.groupBy\",\"PostReaction.aggregate\",\"TopicClosure.findUnique\",\"TopicClosure.findUniqueOrThrow\",\"TopicClosure.findFirst\",\"TopicClosure.findFirstOrThrow\",\"TopicClosure.findMany\",\"TopicClosure.createOne\",\"TopicClosure.createMany\",\"TopicClosure.createManyAndReturn\",\"TopicClosure.updateOne\",\"TopicClosure.updateMany\",\"TopicClosure.updateManyAndReturn\",\"TopicClosure.upsertOne\",\"TopicClosure.deleteOne\",\"TopicClosure.deleteMany\",\"_avg\",\"_sum\",\"TopicClosure.groupBy\",\"TopicClosure.aggregate\",\"TopicWatch.findUnique\",\"TopicWatch.findUniqueOrThrow\",\"TopicWatch.findFirst\",\"TopicWatch.findFirstOrThrow\",\"TopicWatch.findMany\",\"TopicWatch.createOne\",\"TopicWatch.createMany\",\"TopicWatch.createManyAndReturn\",\"TopicWatch.updateOne\",\"TopicWatch.updateMany\",\"TopicWatch.updateManyAndReturn\",\"TopicWatch.upsertOne\",\"TopicWatch.deleteOne\",\"TopicWatch.deleteMany\",\"TopicWatch.groupBy\",\"TopicWatch.aggregate\",\"TopicReadState.findUnique\",\"TopicReadState.findUniqueOrThrow\",\"TopicReadState.findFirst\",\"TopicReadState.findFirstOrThrow\",\"TopicReadState.findMany\",\"TopicReadState.createOne\",\"TopicReadState.createMany\",\"TopicReadState.createManyAndReturn\",\"TopicReadState.updateOne\",\"TopicReadState.updateMany\",\"TopicReadState.updateManyAndReturn\",\"TopicReadState.upsertOne\",\"TopicReadState.deleteOne\",\"TopicReadState.deleteMany\",\"TopicReadState.groupBy\",\"TopicReadState.aggregate\",\"AND\",\"OR\",\"NOT\",\"topicId\",\"memberId\",\"lastReadAt\",\"updatedAt\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"not\",\"contains\",\"startsWith\",\"endsWith\",\"createdAt\",\"ancestorTopicId\",\"descendantTopicId\",\"depth\",\"postId\",\"PostReactionType\",\"reaction\",\"id\",\"parentType\",\"parentId\",\"authorMemberId\",\"authorHandle\",\"content\",\"deletedAt\",\"deletedByMemberId\",\"ipAddress\",\"createdByMemberId\",\"removedAt\",\"removedByMemberId\",\"parentTopicId\",\"challengeId\",\"roleName\",\"title\",\"isAnnouncement\",\"locked\",\"lockedAt\",\"lockedByMemberId\",\"topicId_memberId\",\"ancestorTopicId_descendantTopicId\",\"postId_memberId\",\"every\",\"some\",\"none\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"), + graph: "1QNFgAEZAQAAjwIAIAQAAJACACAJAACRAgAgDAAAkgIAIA0AAJICACAOAACTAgAgDwAAlAIAIJgBAACNAgAwmQEAAAMAEJoBAACNAgAwngFAAPYBACGqAUAA9gEAIbEBAQAAAAG0AQEA9QEAIbUBAQD1AQAhtwFAAPgBACG4AQEA9wEAIb0BAQD3AQAhvgEBAPcBACG_AQEA9wEAIcABAQD1AQAhwQEgAI4CACHCASAAjgIAIcMBQAD4AQAhxAEBAPcBACEBAAAAAQAgGQEAAI8CACAEAACQAgAgCQAAkQIAIAwAAJICACANAACSAgAgDgAAkwIAIA8AAJQCACCYAQAAjQIAMJkBAAADABCaAQAAjQIAMJ4BQAD2AQAhqgFAAPYBACGxAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG3AUAA-AEAIbgBAQD3AQAhvQEBAPcBACG-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_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_ABCaAQAA6wEAMJsBAQDbAQAhngFAANwBACGqAUAA3AEAIbEBAQDbAQAhsgEBANsBACGzAQEA2wEAIbQBAQDbAQAhtQEBANsBACG2AQEA7AEAIbcBQADtAQAhuAEBAOwBACEDAAAABwAgAgAAfgAwIQAAfwAgAwAAAAcAIAIAAAgAMAMAAAkAIAEAAAANACABAAAADQAgAwAAAAsAIAIAAAwAMAMAAA0AIAMAAAALACACAAAMADADAAANACADAAAACwAgAgAADAAwAwAADQAgBgYAALACACCcAQEAAAABngFAAAAAAaoBQAAAAAGuAQEAAAABsAEAAACwAQIBFQAAhwEAIAWcAQEAAAABngFAAAAAAaoBQAAAAAGuAQEAAAABsAEAAACwAQIBFQAAiQEAMAEVAACJAQAwBgYAAK8CACCcAQEAmAIAIZ4BQACZAgAhqgFAAJkCACGuAQEAmAIAIbABAACuArABIgIAAAANACAVAACMAQAgBZwBAQCYAgAhngFAAJkCACGqAUAAmQIAIa4BAQCYAgAhsAEAAK4CsAEiAgAAAAsAIBUAAI4BACACAAAACwAgFQAAjgEAIAMAAAANACAcAACHAQAgHQAAjAEAIAEAAAANACABAAAACwAgAwgAAKsCACAiAACtAgAgIwAArAIAIAiYAQAA5wEAMJkBAACVAQAQmgEAAOcBADCcAQEA2wEAIZ4BQADcAQAhqgFAANwBACGuAQEA2wEAIbABAADoAbABIgMAAAALACACAACUAQAwIQAAlQEAIAMAAAALACACAAAMADADAAANACABAAAAEgAgAQAAABIAIAMAAAAQACACAAARADADAAASACADAAAAEAAgAgAAEQAwAwAAEgAgAwAAABAAIAIAABEAMAMAABIAIAUKAACpAgAgCwAAqgIAIKsBAQAAAAGsAQEAAAABrQECAAAAAQEVAACdAQAgA6sBAQAAAAGsAQEAAAABrQECAAAAAQEVAACfAQAwARUAAJ8BADAFCgAApwIAIAsAAKgCACCrAQEAmAIAIawBAQCYAgAhrQECAKYCACECAAAAEgAgFQAAogEAIAOrAQEAmAIAIawBAQCYAgAhrQECAKYCACECAAAAEAAgFQAApAEAIAIAAAAQACAVAACkAQAgAwAAABIAIBwAAJ0BACAdAACiAQAgAQAAABIAIAEAAAAQ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AAABoAEBAAAABaEBAQAAAAWiAQEAAAABowEBAAAAAaQBAQAAAAGlAQEAAAABpgEBAPIBACGnAQEAAAABqAEBAAAAAakBAQAAAAEJmAEAAPMBADCZAQAAaQAQmgEAAPMBADCqAUAA3AEAIbEBAQDbAQAhuQEBANsBACG6AQEA7AEAIbsBQADtAQAhvAEBAOwBACEJmAEAAPQBADCZAQAAVgAQmgEAAPQBADCqAUAA9gEAIbEBAQD1AQAhuQEBAPUBACG6AQEA9wEAIbsBQAD4AQAhvAEBAPcBACELnwEBAAAAAaABAQAAAAShAQEAAAAEogEBAAAAAaMBAQAAAAGkAQEAAAABpQEBAAAAAaYBAQDhAQAhpwEBAAAAAagBAQAAAAGpAQEAAAABCJ8BQAAAAAGgAUAAAAAEoQFAAAAABKIBQAAAAAGjAUAAAAABpAFAAAAAAaUBQAAAAAGmAUAA3wEAIQufAQEAAAABoAEBAAAABaEBAQAAAAWiAQEAAAABowEBAAAAAaQBAQAAAAGlAQEAAAABpgEBAPIBACGnAQEAAAABqAEBAAAAAakBAQAAAAEInwFAAAAAAaABQAAAAAWhAUAAAAAFogFAAAAAAaMBQAAAAAGkAUAAAAABpQFAAAAAAaYBQADwAQAhCZgBAAD5AQAwmQEAAFAAEJoBAAD5AQAwnAEBANsBACGqAUAA3AEAIbEBAQDbAQAhugEBAOwBACG7AUAA7QEAIbwBAQDsAQAhCZgBAAD6AQAwmQEAAD0AEJoBAAD6AQAwnAEBAPUBACGqAUAA9gEAIbEBAQD1AQAhugEBAPcBACG7AUAA-AEAIbwBAQD3AQAhEpgBAAD7AQAwmQEAADcAEJoBAAD7AQAwngFAANwBACGqAUAA3AEAIbEBAQDbAQAhtAEBANsBACG1AQEA2wEAIbcBQADtAQAhuAEBAOwBACG9AQEA7AEAIb4BAQDsAQAhvwEBAOwBACHAAQEA2wEAIcEBIAD8AQAhwgEgAPwBACHDAUAA7QEAIcQBAQDsAQAhBQgAAN4BACAiAAD-AQAgIwAA_gEAIJ8BIAAAAAGmASAA_QEAIQUIAADeAQAgIgAA_gEAICMAAP4BACCfASAAAAABpgEgAP0BACECnwEgAAAAAaYBIAD-AQAhApsBAQAAAAGcAQEAAAABCAUAAIECACCYAQAAgAIAMJkBAAAZABCaAQAAgAIAMJsBAQD1AQAhnAEBAPUBACGdAUAA9gEAIZ4BQAD2AQAhGwEAAI8CACAEAACQAgAgCQAAkQIAIAwAAJICACANAACSAgAgDgAAkwIAIA8AAJQCACCYAQAAjQIAMJkBAAADABCaAQAAjQIAMJ4BQAD2AQAhqgFAAPYBACGxAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG3AUAA-AEAIbgBAQD3AQAhvQEBAPcBACG-AQEA9wEAIb8BAQD3AQAhwAEBAPUBACHBASAAjgIAIcIBIACOAgAhwwFAAPgBACHEAQEA9wEAIcsBAAADACDMAQAAAwAgApsBAQAAAAGcAQEAAAABBwUAAIECACCYAQAAgwIAMJkBAAAVABCaAQAAgwIAMJsBAQD1AQAhnAEBAPUBACGqAUAA9gEAIQKrAQEAAAABrAEBAAAAAQgKAACBAgAgCwAAgQIAIJgBAACFAgAwmQEAABAAEJoBAACFAgAwqwEBAPUBACGsAQEA9QEAIa0BAgCGAgAhCJ8BAgAAAAGgAQIAAAAEoQECAAAABKIBAgAAAAGjAQIAAAABpAECAAAAAaUBAgAAAAGmAQIA3gEAIQKcAQEAAAABrgEBAAAAAQkGAACKAgAgmAEAAIgCADCZAQAACwAQmgEAAIgCADCcAQEA9QEAIZ4BQAD2AQAhqgFAAPYBACGuAQEA9QEAIbABAACJArABIgSfAQAAALABAqABAAAAsAEIoQEAAACwAQimAQAA6gGwASISBQAAgQIAIAcAAIwCACCYAQAAiwIAMJkBAAAHABCaAQAAiwIAMJsBAQD1AQAhngFAAPYBACGqAUAA9gEAIbEBAQD1AQAhsgEBAPUBACGzAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG2AQEA9wEAIbcBQAD4AQAhuAEBAPcBACHLAQAABwAgzAEAAAcAIBAFAACBAgAgBwAAjAIAIJgBAACLAgAwmQEAAAcAEJoBAACLAgAwmwEBAPUBACGeAUAA9gEAIaoBQAD2AQAhsQEBAPUBACGyAQEA9QEAIbMBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbYBAQD3AQAhtwFAAPgBACG4AQEA9wEAIQPIAQAACwAgyQEAAAsAIMoBAAALACAZAQAAjwIAIAQAAJACACAJAACRAgAgDAAAkgIAIA0AAJICACAOAACTAgAgDwAAlAIAIJgBAACNAgAwmQEAAAMAEJoBAACNAgAwngFAAPYBACGqAUAA9gEAIbEBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbcBQAD4AQAhuAEBAPcBACG9AQEA9wEAIb4BAQD3AQAhvwEBAPcBACHAAQEA9QEAIcEBIACOAgAhwgEgAI4CACHDAUAA-AEAIcQBAQD3AQAhAp8BIAAAAAGmASAA_gEAIRsBAACPAgAgBAAAkAIAIAkAAJECACAMAACSAgAgDQAAkgIAIA4AAJMCACAPAACUAgAgmAEAAI0CADCZAQAAAwAQmgEAAI0CADCeAUAA9gEAIaoBQAD2AQAhsQEBAPUBACG0AQEA9QEAIbUBAQD1AQAhtwFAAPgBACG4AQEA9wEAIb0BAQD3AQAhvgEBAPcBACG_AQEA9wEAIcABAQD1AQAhwQEgAI4CACHCASAAjgIAIcMBQAD4AQAhxAEBAPcBACHLAQAAAwAgzAEAAAMAIAPIAQAAAwAgyQEAAAMAIMoBAAADACADyAEAAAcAIMkBAAAHACDKAQAABwAgA8gBAAAQACDJAQAAEAAgygEAABAAIAPIAQAAFQAgyQEAABUAIMoBAAAVACADyAEAABkAIMkBAAAZACDKAQAAGQAgAAAAAdABAQAAAAEB0AFAAAAAAQUcAADRAwAgHQAA1AMAIM0BAADSAwAgzgEAANMDACDTAQAAAQAgAxwAANEDACDNAQAA0gMAINMBAAABACAAAAAFHAAAzAMAIB0AAM8DACDNAQAAzQMAIM4BAADOAwAg0wEAAAEAIAMcAADMAwAgzQEAAM0DACDTAQAAAQAgAAAAAAAF0AECAAAAAdYBAgAAAAHXAQIAAAAB2AECAAAAAdkBAgAAAAEFHAAAxAMAIB0AAMoDACDNAQAAxQMAIM4BAADJAwAg0wEAAAEAIAUcAADCAwAgHQAAxwMAIM0BAADDAwAgzgEAAMYDACDTAQAAAQAgAxwAAMQDACDNAQAAxQMAINMBAAABACADHAAAwgMAIM0BAADDAwAg0wEAAAEAIAAAAAHQAQAAALABAgUcAAC9AwAgHQAAwAMAIM0BAAC-AwAgzgEAAL8DACDTAQAACQAgAxwAAL0DACDNAQAAvgMAINMBAAAJACAAAAAAAdABAQAAAAEB0AFAAAAAAQUcAAC3AwAgHQAAuwMAIM0BAAC4AwAgzgEAALoDACDTAQAAAQAgCxwAALkCADAdAAC-AgAwzQEAALoCADDOAQAAuwIAMM8BAAC8AgAg0AEAAL0CADDRAQAAvQIAMNIBAAC9AgAw0wEAAL0CADDUAQAAvwIAMNUBAADAAgAwBJwBAQAAAAGeAUAAAAABqgFAAAAAAbABAAAAsAECAgAAAA0AIBwAAMQCACADAAAADQAgHAAAxAIAIB0AAMMCACABFQAAuQMAMAoGAACKAgAgmAEAAIgCADCZAQAACwAQmgEAAIgCADCcAQEA9QEAIZ4BQAD2AQAhqgFAAPYBACGuAQEA9QEAIbABAACJArABIscBAACHAgAgAgAAAA0AIBUAAMMCACACAAAAwQIAIBUAAMICACAImAEAAMACADCZAQAAwQIAEJoBAADAAgAwnAEBAPUBACGeAUAA9gEAIaoBQAD2AQAhrgEBAPUBACGwAQAAiQKwASIImAEAAMACADCZAQAAwQIAEJoBAADAAgAwnAEBAPUBACGeAUAA9gEAIaoBQAD2AQAhrgEBAPUBACGwAQAAiQKwASIEnAEBAJgCACGeAUAAmQIAIaoBQACZAgAhsAEAAK4CsAEiBJwBAQCYAgAhngFAAJkCACGqAUAAmQIAIbABAACuArABIgScAQEAAAABngFAAAAAAaoBQAAAAAGwAQAAALABAgMcAAC3AwAgzQEAALgDACDTAQAAAQAgBBwAALkCADDNAQAAugIAMM8BAAC8AgAg0wEAAL0CADAAAAAAAAAAAAAB0AEgAAAAAQccAACsAwAgHQAAtQMAIM0BAACtAwAgzgEAALQDACDRAQAAAwAg0gEAAAMAINMBAAABACALHAAAkQMAMB0AAJYDADDNAQAAkgMAMM4BAACTAwAwzwEAAJQDACDQAQAAlQMAMNEBAACVAwAw0gEAAJUDADDTAQAAlQMAMNQBAACXAwAw1QEAAJgDADALHAAAhQMAMB0AAIoDADDNAQAAhgMAMM4BAACHAwAwzwEAAIgDACDQAQAAiQMAMNEBAACJAwAw0gEAAIkDADDTAQAAiQMAMNQBAACLAwAw1QEAAIwDADALHAAA_AIAMB0AAIADADDNAQAA_QIAMM4BAAD-AgAwzwEAAP8CACDQAQAA9AIAMNEBAAD0AgAw0gEAAPQCADDTAQAA9AIAMNQBAACBAwAw1QEAAPcCADALHAAA8AIAMB0AAPUCADDNAQAA8QIAMM4BAADyAgAwzwEAAPMCACDQAQAA9AIAMNEBAAD0AgAw0gEAAPQCADDTAQAA9AIAMNQBAAD2AgAw1QEAAPcCADALHAAA5AIAMB0AAOkCADDNAQAA5QIAMM4BAADmAgAwzwEAAOcCACDQAQAA6AIAMNEBAADoAgAw0gEAAOgCADDTAQAA6AIAMNQBAADqAgAw1QEAAOsCADALHAAA2AIAMB0AAN0CADDNAQAA2QIAMM4BAADaAgAwzwEAANsCACDQAQAA3AIAMNEBAADcAgAw0gEAANwCADDTAQAA3AIAMNQBAADeAgAw1QEAAN8CADADnAEBAAAAAZ0BQAAAAAGeAUAAAAABAgAAABsAIBwAAOMCACADAAAAGwAgHAAA4wIAIB0AAOICACABFQAAswMAMAkFAACBAgAgmAEAAIACADCZAQAAGQAQmgEAAIACADCbAQEA9QEAIZwBAQD1AQAhnQFAAPYBACGeAUAA9gEAIcUBAAD_AQAgAgAAABsAIBUAAOICACACAAAA4AIAIBUAAOECACAHmAEAAN8CADCZAQAA4AIAEJoBAADfAgAwmwEBAPUBACGcAQEA9QEAIZ0BQAD2AQAhngFAAPYBACEHmAEAAN8CADCZAQAA4AIAEJoBAADfAgAwmwEBAPUBACGcAQEA9QEAIZ0BQAD2AQAhngFAAPYBACEDnAEBAJgCACGdAUAAmQIAIZ4BQACZAgAhA5wBAQCYAgAhnQFAAJkCACGeAUAAmQIAIQOcAQEAAAABnQFAAAAAAZ4BQAAAAAECnAEBAAAAAaoBQAAAAAECAAAAFwAgHAAA7wIAIAMAAAAXACAcAADvAgAgHQAA7gIAIAEVAACyAwAwCAUAAIECACCYAQAAgwIAMJkBAAAVABCaAQAAgwIAMJsBAQD1AQAhnAEBAPUBACGqAUAA9gEAIcUBAACCAgAgAgAAABcAIBUAAO4CACACAAAA7AIAIBUAAO0CACAGmAEAAOsCADCZAQAA7AIAEJoBAADrAgAwmwEBAPUBACGcAQEA9QEAIaoBQAD2AQAhBpgBAADrAgAwmQEAAOwCABCaAQAA6wIAMJsBAQD1AQAhnAEBAPUBACGqAUAA9gEAIQKcAQEAmAIAIaoBQACZAgAhApwBAQCYAgAhqgFAAJkCACECnAEBAAAAAaoBQAAAAAEDCgAAqQIAIKsBAQAAAAGtAQIAAAABAgAAABIAIBwAAPsCACADAAAAEgAgHAAA-wIAIB0AAPoCACABFQAAsQMAMAkKAACBAgAgCwAAgQIAIJgBAACFAgAwmQEAABAAEJoBAACFAgAwqwEBAPUBACGsAQEA9QEAIa0BAgCGAgAhxgEAAIQCACACAAAAEgAgFQAA-gIAIAIAAAD4AgAgFQAA-QIAIAaYAQAA9wIAMJkBAAD4AgAQmgEAAPcCADCrAQEA9QEAIawBAQD1AQAhrQECAIYCACEGmAEAAPcCADCZAQAA-AIAEJoBAAD3AgAwqwEBAPUBACGsAQEA9QEAIa0BAgCGAgAhAqsBAQCYAgAhrQECAKYCACEDCgAApwIAIKsBAQCYAgAhrQECAKYCACEDCgAAqQIAIKsBAQAAAAGtAQIAAAABAwsAAKoCACCsAQEAAAABrQECAAAAAQIAAAASACAcAACEAwAgAwAAABIAIBwAAIQDACAdAACDAwAgARUAALADADACAAAAEgAgFQAAgwMAIAIAAAD4AgAgFQAAggMAIAKsAQEAmAIAIa0BAgCmAgAhAwsAAKgCACCsAQEAmAIAIa0BAgCmAgAhAwsAAKoCACCsAQEAAAABrQECAAAAAQsHAADGAgAgngFAAAAAAaoBQAAAAAGxAQEAAAABsgEBAAAAAbMBAQAAAAG0AQEAAAABtQEBAAAAAbYBAQAAAAG3AUAAAAABuAEBAAAAAQIAAAAJACAcAACQAwAgAwAAAAkAIBwAAJADACAdAACPAwAgARUAAK8DADAQBQAAgQIAIAcAAIwCACCYAQAAiwIAMJkBAAAHABCaAQAAiwIAMJsBAQD1AQAhngFAAPYBACGqAUAA9gEAIbEBAQAAAAGyAQEA9QEAIbMBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbYBAQD3AQAhtwFAAPgBACG4AQEA9wEAIQIAAAAJACAVAACPAwAgAgAAAI0DACAVAACOAwAgDpgBAACMAwAwmQEAAI0DABCaAQAAjAMAMJsBAQD1AQAhngFAAPYBACGqAUAA9gEAIbEBAQD1AQAhsgEBAPUBACGzAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG2AQEA9wEAIbcBQAD4AQAhuAEBAPcBACEOmAEAAIwDADCZAQAAjQMAEJoBAACMAwAwmwEBAPUBACGeAUAA9gEAIaoBQAD2AQAhsQEBAPUBACGyAQEA9QEAIbMBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbYBAQD3AQAhtwFAAPgBACG4AQEA9wEAIQqeAUAAmQIAIaoBQACZAgAhsQEBAJgCACGyAQEAmAIAIbMBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbYBAQC1AgAhtwFAALYCACG4AQEAtQIAIQsHAAC4AgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhsgEBAJgCACGzAQEAmAIAIbQBAQCYAgAhtQEBAJgCACG2AQEAtQIAIbcBQAC2AgAhuAEBALUCACELBwAAxgIAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbIBAQAAAAGzAQEAAAABtAEBAAAAAbUBAQAAAAG2AQEAAAABtwFAAAAAAbgBAQAAAAEUBAAAnQMAIAkAAJ4DACAMAACfAwAgDQAAoAMAIA4AAKEDACAPAACiAwAgngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAAAAAcEBIAAAAAHCASAAAAABwwFAAAAAAcQBAQAAAAECAAAAAQAgHAAAnAMAIAMAAAABACAcAACcAwAgHQAAmwMAIAEVAACuAwAwGQEAAI8CACAEAACQAgAgCQAAkQIAIAwAAJICACANAACSAgAgDgAAkwIAIA8AAJQCACCYAQAAjQIAMJkBAAADABCaAQAAjQIAMJ4BQAD2AQAhqgFAAPYBACGxAQEAAAABtAEBAPUBACG1AQEA9QEAIbcBQAD4AQAhuAEBAPcBACG9AQEA9wEAIb4BAQD3AQAhvwEBAPcBACHAAQEA9QEAIcEBIACOAgAhwgEgAI4CACHDAUAA-AEAIcQBAQD3AQAhAgAAAAEAIBUAAJsDACACAAAAmQMAIBUAAJoDACASmAEAAJgDADCZAQAAmQMAEJoBAACYAwAwngFAAPYBACGqAUAA9gEAIbEBAQD1AQAhtAEBAPUBACG1AQEA9QEAIbcBQAD4AQAhuAEBAPcBACG9AQEA9wEAIb4BAQD3AQAhvwEBAPcBACHAAQEA9QEAIcEBIACOAgAhwgEgAI4CACHDAUAA-AEAIcQBAQD3AQAhEpgBAACYAwAwmQEAAJkDABCaAQAAmAMAMJ4BQAD2AQAhqgFAAPYBACGxAQEA9QEAIbQBAQD1AQAhtQEBAPUBACG3AUAA-AEAIbgBAQD3AQAhvQEBAPcBACG-AQEA9wEAIb8BAQD3AQAhwAEBAPUBACHBASAAjgIAIcIBIACOAgAhwwFAAPgBACHEAQEA9wEAIQ6eAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhFAQAANICACAJAADTAgAgDAAA1AIAIA0AANUCACAOAADWAgAgDwAA1wIAIJ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbQBAQCYAgAhtQEBAJgCACG3AUAAtgIAIbgBAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEUBAAAnQMAIAkAAJ4DACAMAACfAwAgDQAAoAMAIA4AAKEDACAPAACiAwAgngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAAAAAcEBIAAAAAHCASAAAAABwwFAAAAAAcQBAQAAAAEEHAAAkQMAMM0BAACSAwAwzwEAAJQDACDTAQAAlQMAMAQcAACFAwAwzQEAAIYDADDPAQAAiAMAINMBAACJAwAwBBwAAPwCADDNAQAA_QIAMM8BAAD_AgAg0wEAAPQCADAEHAAA8AIAMM0BAADxAgAwzwEAAPMCACDTAQAA9AIAMAQcAADkAgAwzQEAAOUCADDPAQAA5wIAINMBAADoAgAwBBwAANgCADDNAQAA2QIAMM8BAADbAgAg0wEAANwCADADHAAArAMAIM0BAACtAwAg0wEAAAEAIA4BAACkAwAgBAAApwMAIAkAAKgDACAMAACpAwAgDQAAqQMAIA4AAKoDACAPAACrAwAgtwEAALECACC4AQAAsQIAIL0BAACxAgAgvgEAALECACC_AQAAsQIAIMMBAACxAgAgxAEAALECACAFBQAApAMAIAcAAKYDACC2AQAAsQIAILcBAACxAgAguAEAALECACAAAAAAAAAVAQAAowMAIAkAAJ4DACAMAACfAwAgDQAAoAMAIA4AAKEDACAPAACiAwAgngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb0BAQAAAAG-AQEAAAABvwEBAAAAAcABAQAAAAHBASAAAAABwgEgAAAAAcMBQAAAAAHEAQEAAAABAgAAAAEAIBwAAKwDACAOngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb4BAQAAAAG_AQEAAAABwAEBAAAAAcEBIAAAAAHCASAAAAABwwFAAAAAAcQBAQAAAAEKngFAAAAAAaoBQAAAAAGxAQEAAAABsgEBAAAAAbMBAQAAAAG0AQEAAAABtQEBAAAAAbYBAQAAAAG3AUAAAAABuAEBAAAAAQKsAQEAAAABrQECAAAAAQKrAQEAAAABrQECAAAAAQKcAQEAAAABqgFAAAAAAQOcAQEAAAABnQFAAAAAAZ4BQAAAAAEDAAAAAwAgHAAArAMAIB0AALYDACAXAAAAAwAgAQAA0QIAIAkAANMCACAMAADUAgAgDQAA1QIAIA4AANYCACAPAADXAgAgFQAAtgMAIJ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbQBAQCYAgAhtQEBAJgCACG3AUAAtgIAIbgBAQC1AgAhvQEBALUCACG-AQEAtQIAIb8BAQC1AgAhwAEBAJgCACHBASAA0AIAIcIBIADQAgAhwwFAALYCACHEAQEAtQIAIRUBAADRAgAgCQAA0wIAIAwAANQCACANAADVAgAgDgAA1gIAIA8AANcCACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAAowMAIAQAAJ0DACAMAACfAwAgDQAAoAMAIA4AAKEDACAPAACiAwAgngFAAAAAAaoBQAAAAAGxAQEAAAABtAEBAAAAAbUBAQAAAAG3AUAAAAABuAEBAAAAAb0BAQAAAAG-AQEAAAABvwEBAAAAAcABAQAAAAHBASAAAAABwgEgAAAAAcMBQAAAAAHEAQEAAAABAgAAAAEAIBwAALcDACAEnAEBAAAAAZ4BQAAAAAGqAUAAAAABsAEAAACwAQIDAAAAAwAgHAAAtwMAIB0AALwDACAXAAAAAwAgAQAA0QIAIAQAANICACAMAADUAgAgDQAA1QIAIA4AANYCACAPAADXAgAgFQAAvAMAIJ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbQBAQCYAgAhtQEBAJgCACG3AUAAtgIAIbgBAQC1AgAhvQEBALUCACG-AQEAtQIAIb8BAQC1AgAhwAEBAJgCACHBASAA0AIAIcIBIADQAgAhwwFAALYCACHEAQEAtQIAIRUBAADRAgAgBAAA0gIAIAwAANQCACANAADVAgAgDgAA1gIAIA8AANcCACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEMBQAAxQIAIJsBAQAAAAGeAUAAAAABqgFAAAAAAbEBAQAAAAGyAQEAAAABswEBAAAAAbQBAQAAAAG1AQEAAAABtgEBAAAAAbcBQAAAAAG4AQEAAAABAgAAAAkAIBwAAL0DACADAAAABwAgHAAAvQMAIB0AAMEDACAOAAAABwAgBQAAtwIAIBUAAMEDACCbAQEAmAIAIZ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbIBAQCYAgAhswEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtgEBALUCACG3AUAAtgIAIbgBAQC1AgAhDAUAALcCACCbAQEAmAIAIZ4BQACZAgAhqgFAAJkCACGxAQEAmAIAIbIBAQCYAgAhswEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtgEBALUCACG3AUAAtgIAIbgBAQC1AgAhFQEAAKMDACAEAACdAwAgCQAAngMAIAwAAJ8DACAOAAChAwAgDwAAogMAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbQBAQAAAAG1AQEAAAABtwFAAAAAAbgBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAAAABwQEgAAAAAcIBIAAAAAHDAUAAAAABxAEBAAAAAQIAAAABACAcAADCAwAgFQEAAKMDACAEAACdAwAgCQAAngMAIA0AAKADACAOAAChAwAgDwAAogMAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbQBAQAAAAG1AQEAAAABtwFAAAAAAbgBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAAAABwQEgAAAAAcIBIAAAAAHDAUAAAAABxAEBAAAAAQIAAAABACAcAADEAwAgAwAAAAMAIBwAAMIDACAdAADIAwAgFwAAAAMAIAEAANECACAEAADSAgAgCQAA0wIAIAwAANQCACAOAADWAgAgDwAA1wIAIBUAAMgDACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAA0QIAIAQAANICACAJAADTAgAgDAAA1AIAIA4AANYCACAPAADXAgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbcBQAC2AgAhuAEBALUCACG9AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhAwAAAAMAIBwAAMQDACAdAADLAwAgFwAAAAMAIAEAANECACAEAADSAgAgCQAA0wIAIA0AANUCACAOAADWAgAgDwAA1wIAIBUAAMsDACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAA0QIAIAQAANICACAJAADTAgAgDQAA1QIAIA4AANYCACAPAADXAgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbcBQAC2AgAhuAEBALUCACG9AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhFQEAAKMDACAEAACdAwAgCQAAngMAIAwAAJ8DACANAACgAwAgDwAAogMAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbQBAQAAAAG1AQEAAAABtwFAAAAAAbgBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAAAABwQEgAAAAAcIBIAAAAAHDAUAAAAABxAEBAAAAAQIAAAABACAcAADMAwAgAwAAAAMAIBwAAMwDACAdAADQAwAgFwAAAAMAIAEAANECACAEAADSAgAgCQAA0wIAIAwAANQCACANAADVAgAgDwAA1wIAIBUAANADACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAA0QIAIAQAANICACAJAADTAgAgDAAA1AIAIA0AANUCACAPAADXAgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbcBQAC2AgAhuAEBALUCACG9AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhFQEAAKMDACAEAACdAwAgCQAAngMAIAwAAJ8DACANAACgAwAgDgAAoQMAIJ4BQAAAAAGqAUAAAAABsQEBAAAAAbQBAQAAAAG1AQEAAAABtwFAAAAAAbgBAQAAAAG9AQEAAAABvgEBAAAAAb8BAQAAAAHAAQEAAAABwQEgAAAAAcIBIAAAAAHDAUAAAAABxAEBAAAAAQIAAAABACAcAADRAwAgAwAAAAMAIBwAANEDACAdAADVAwAgFwAAAAMAIAEAANECACAEAADSAgAgCQAA0wIAIAwAANQCACANAADVAgAgDgAA1gIAIBUAANUDACCeAUAAmQIAIaoBQACZAgAhsQEBAJgCACG0AQEAmAIAIbUBAQCYAgAhtwFAALYCACG4AQEAtQIAIb0BAQC1AgAhvgEBALUCACG_AQEAtQIAIcABAQCYAgAhwQEgANACACHCASAA0AIAIcMBQAC2AgAhxAEBALUCACEVAQAA0QIAIAQAANICACAJAADTAgAgDAAA1AIAIA0AANUCACAOAADWAgAgngFAAJkCACGqAUAAmQIAIbEBAQCYAgAhtAEBAJgCACG1AQEAmAIAIbcBQAC2AgAhuAEBALUCACG9AQEAtQIAIb4BAQC1AgAhvwEBALUCACHAAQEAmAIAIcEBIADQAgAhwgEgANACACHDAUAAtgIAIcQBAQC1AgAhCAEEAQQGAQgACAkKAgwTBQ0UBQ4YBg8cBwMFAAEHDgMIAAQBBgACAQcPAAIKAAELAAEBBQABAQUAAQYEHQAJHgAMHwANIAAOIQAPIgAAAQEsAQEBMgEDCAANIgAOIwAPAAAAAwgADSIADiMADwAAAAMIABUiABYjABcAAAADCAAVIgAWIwAXAAAAAwgAHSIAHiMAHwAAAAMIAB0iAB4jAB8BBQABAQUAAQMIACQiACUjACYAAAADCAAkIgAlIwAmAQYAAgEGAAIDCAArIgAsIwAtAAAAAwgAKyIALCMALQIKAAELAAECCgABCwABBQgAMiIANSMANnQAM3UANAAAAAAABQgAMiIANSMANnQAM3UANAEFAAEBBQABAwgAOyIAPCMAPQAAAAMIADsiADwjAD0BBQABAQUAAQMIAEIiAEMjAEQAAAADCABCIgBDIwBEEAIBESMBEiQBEyUBFCYBFigBFyoJGCsKGS4BGjAJGzELHjMBHzQBIDUJJDgMJTkQJjsRJzwRKD8RKUARKkERK0MRLEUJLUYSLkgRL0oJMEsTMUwRMk0RM04JNFEUNVIYNlQZN1UZOFgZOVkZOloZO1wZPF4JPV8aPmEZP2MJQGQbQWUZQmYZQ2cJRGocRWsgRmwCR20CSG4CSW8CSnACS3ICTHQJTXUhTncCT3kJUHoiUXsCUnwCU30JVIABI1WBASdWggEDV4MBA1iEAQNZhQEDWoYBA1uIAQNcigEJXYsBKF6NAQNfjwEJYJABKWGRAQNikgEDY5MBCWSWASpllwEuZpgBBWeZAQVomgEFaZsBBWqcAQVrngEFbKABCW2hAS9uowEFb6UBCXCmATBxpwEFcqgBBXOpAQl2rAExd60BN3iuAQZ5rwEGerABBnuxAQZ8sgEGfbQBBn62AQl_twE4gAG5AQaBAbsBCYIBvAE5gwG9AQaEAb4BBoUBvwEJhgHCATqHAcMBPogBxAEHiQHFAQeKAcYBB4sBxwEHjAHIAQeNAcoBB44BzAEJjwHNAT-QAc8BB5EB0QEJkgHSAUCTAdMBB5QB1AEHlQHVAQmWAdgBQZcB2QFF" } config.compilerWasm = { getRuntime: async () => require('./query_compiler_fast_bg.js'), diff --git a/packages/forums-prisma-client/package.json b/packages/forums-prisma-client/package.json index 25a23d1..8779070 100644 --- a/packages/forums-prisma-client/package.json +++ b/packages/forums-prisma-client/package.json @@ -1,5 +1,5 @@ { - "name": "prisma-client-9191bf60429fafe5f278fa5f503fb7388dd9fe11117f6413411a46164ded1602", + "name": "prisma-client-ef34779367716a040c952441ff72fcb57b8c12c5a26fab35714dccb03ead1789", "main": "index.js", "types": "index.d.ts", "browser": "default.js", diff --git a/packages/forums-prisma-client/schema.prisma b/packages/forums-prisma-client/schema.prisma index 835a324..b836603 100644 --- a/packages/forums-prisma-client/schema.prisma +++ b/packages/forums-prisma-client/schema.prisma @@ -14,6 +14,13 @@ datasource db { schemas = ["forums"] } +enum PostReactionType { + THUMBS_UP + THUMBS_DOWN + + @@schema("forums") +} + model Topic { id String @id @default(dbgenerated("nanoid()")) @db.VarChar(14) parentTopicId String? @db.VarChar(14) @@ -86,7 +93,8 @@ model Post { deletedAt DateTime? deletedByMemberId String? @db.VarChar(64) - topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade) + topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade) + reactions PostReaction[] @@index([topicId, createdAt]) @@index([topicId, parentType, parentId]) @@ -94,6 +102,21 @@ model Post { @@schema("forums") } +model PostReaction { + postId String @db.VarChar(14) + memberId String @db.VarChar(64) + reaction PostReactionType + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + + post Post @relation(fields: [postId], references: [id], onDelete: Cascade) + + @@id([postId, memberId]) + @@index([memberId]) + @@index([postId, reaction]) + @@schema("forums") +} + model TopicClosure { ancestorTopicId String @db.VarChar(14) descendantTopicId String @db.VarChar(14) diff --git a/prisma/migrations/20260827120000_post_reactions/migration.sql b/prisma/migrations/20260827120000_post_reactions/migration.sql new file mode 100644 index 0000000..706fd37 --- /dev/null +++ b/prisma/migrations/20260827120000_post_reactions/migration.sql @@ -0,0 +1,22 @@ +-- CreateEnum +CREATE TYPE "forums"."PostReactionType" AS ENUM ('THUMBS_UP', 'THUMBS_DOWN'); + +-- CreateTable +CREATE TABLE "forums"."PostReaction" ( + "postId" VARCHAR(14) NOT NULL, + "memberId" VARCHAR(64) NOT NULL, + "reaction" "forums"."PostReactionType" NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "PostReaction_pkey" PRIMARY KEY ("postId", "memberId") +); + +-- CreateIndex +CREATE INDEX "PostReaction_memberId_idx" ON "forums"."PostReaction"("memberId"); + +-- CreateIndex +CREATE INDEX "PostReaction_postId_reaction_idx" ON "forums"."PostReaction"("postId", "reaction"); + +-- AddForeignKey +ALTER TABLE "forums"."PostReaction" ADD CONSTRAINT "PostReaction_postId_fkey" FOREIGN KEY ("postId") REFERENCES "forums"."Post"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 835a324..b836603 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -14,6 +14,13 @@ datasource db { schemas = ["forums"] } +enum PostReactionType { + THUMBS_UP + THUMBS_DOWN + + @@schema("forums") +} + model Topic { id String @id @default(dbgenerated("nanoid()")) @db.VarChar(14) parentTopicId String? @db.VarChar(14) @@ -86,7 +93,8 @@ model Post { deletedAt DateTime? deletedByMemberId String? @db.VarChar(64) - topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade) + topic Topic @relation(fields: [topicId], references: [id], onDelete: Cascade) + reactions PostReaction[] @@index([topicId, createdAt]) @@index([topicId, parentType, parentId]) @@ -94,6 +102,21 @@ model Post { @@schema("forums") } +model PostReaction { + postId String @db.VarChar(14) + memberId String @db.VarChar(64) + reaction PostReactionType + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + + post Post @relation(fields: [postId], references: [id], onDelete: Cascade) + + @@id([postId, memberId]) + @@index([memberId]) + @@index([postId, reaction]) + @@schema("forums") +} + model TopicClosure { ancestorTopicId String @db.VarChar(14) descendantTopicId String @db.VarChar(14) diff --git a/src/forums/dto/forums-command-response.dto.ts b/src/forums/dto/forums-command-response.dto.ts index 7d9a17f..afc6082 100644 --- a/src/forums/dto/forums-command-response.dto.ts +++ b/src/forums/dto/forums-command-response.dto.ts @@ -1,4 +1,5 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { PostReactionType } from '../../../prisma/generated/client'; /** * Topic response returned by command-side forum endpoints. @@ -184,3 +185,27 @@ export class TopicReadStateCommandResponseDto { @ApiProperty({ description: 'Read-state update timestamp.' }) updatedAt: Date; } + +/** + * Aggregate reaction state returned after a member sets or removes a reaction. + * + * Counts include all members' current reactions. `viewerReaction` is the + * authenticated member's resulting value and is null after removal. + */ +export class ForumPostReactionStateDto { + @ApiProperty({ description: 'Post whose reaction state changed.' }) + postId: string; + + @ApiPropertyOptional({ + description: 'Current member reaction after the command.', + enum: PostReactionType, + nullable: true, + }) + viewerReaction: PostReactionType | null; + + @ApiProperty({ description: 'Current number of thumbs-up reactions.' }) + thumbsUpCount: number; + + @ApiProperty({ description: 'Current number of thumbs-down reactions.' }) + thumbsDownCount: number; +} diff --git a/src/forums/dto/forums-command.dto.ts b/src/forums/dto/forums-command.dto.ts index 8708625..8ddd98f 100644 --- a/src/forums/dto/forums-command.dto.ts +++ b/src/forums/dto/forums-command.dto.ts @@ -1,12 +1,14 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsBoolean, + IsEnum, IsIn, IsOptional, IsString, MaxLength, MinLength, } from 'class-validator'; +import { PostReactionType } from '../../../prisma/generated/client'; /** * Request body for creating a topic with its starter post. @@ -170,3 +172,18 @@ export class UpdatePostDto { @MinLength(1) content: string; } + +/** + * Request body for setting the authenticated member's reaction on a post. + * + * A member has at most one reaction per post. Sending the other reaction type + * replaces the existing value; removing a reaction uses the DELETE endpoint. + */ +export class SetPostReactionDto { + @ApiProperty({ + description: 'Thumb reaction to add or replace for the current member.', + enum: PostReactionType, + }) + @IsEnum(PostReactionType) + reaction: PostReactionType; +} diff --git a/src/forums/dto/forums-read.dto.ts b/src/forums/dto/forums-read.dto.ts index c64409a..b236add 100644 --- a/src/forums/dto/forums-read.dto.ts +++ b/src/forums/dto/forums-read.dto.ts @@ -1,6 +1,7 @@ import { Type } from 'class-transformer'; import { IsInt, IsOptional, Min } from 'class-validator'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { PostReactionType } from '../../../prisma/generated/client'; /** * Query parameters for paginated forum topic list reads. @@ -293,6 +294,23 @@ export class ForumsPostTreeNodeDto { @ApiProperty({ description: 'Whether the post is a deleted placeholder.' }) deleted: boolean; + @ApiProperty({ + description: 'Number of current thumbs-up reactions from all members.', + }) + thumbsUpCount: number; + + @ApiProperty({ + description: 'Number of current thumbs-down reactions from all members.', + }) + thumbsDownCount: number; + + @ApiPropertyOptional({ + description: "Authenticated member's current reaction on this post.", + enum: PostReactionType, + nullable: true, + }) + viewerReaction: PostReactionType | null; + @ApiProperty({ description: 'Nested replies ordered by newest visible subtree activity.', type: () => [ForumsPostTreeNodeDto], diff --git a/src/forums/forums-command.service.spec.ts b/src/forums/forums-command.service.spec.ts index f06d841..0b22530 100644 --- a/src/forums/forums-command.service.spec.ts +++ b/src/forums/forums-command.service.spec.ts @@ -1,6 +1,6 @@ import { Logger } from '@nestjs/common'; import { JwtUser } from '../auth/jwt.service'; -import { Post, Topic } from '../../prisma/generated/client'; +import { Post, PostReactionType, Topic } from '../../prisma/generated/client'; import { ForumsCommandService } from './forums-command.service'; const createdAt = new Date('2026-06-04T00:00:00.000Z'); @@ -84,6 +84,20 @@ function createCommandService(order: string[] = []) { findUnique: jest.fn().mockResolvedValue(post), update: jest.fn().mockResolvedValue(post), }, + postReaction: { + upsert: jest.fn().mockResolvedValue({ + postId: 'post-1', + memberId: '1', + reaction: PostReactionType.THUMBS_UP, + createdAt, + updatedAt: createdAt, + }), + deleteMany: jest.fn().mockResolvedValue({ count: 1 }), + count: jest.fn().mockImplementation( + (args: { where: { reaction: PostReactionType } }) => + args.where.reaction === PostReactionType.THUMBS_UP ? 2 : 1, + ), + }, topicClosure: { findFirst: jest.fn().mockResolvedValue(null), findMany: jest.fn().mockResolvedValue([]), @@ -129,6 +143,7 @@ function createCommandService(order: string[] = []) { canUpdateTopic: { allowed: true }, }), decideForPost: jest.fn().mockResolvedValue({ + canView: { allowed: true }, canDeletePost: { allowed: true }, canUpdatePost: { allowed: true }, }), @@ -560,6 +575,88 @@ describe('ForumsCommandService notification boundary', () => { }); }); +describe('ForumsCommandService post reactions', () => { + it('upserts a member reaction and returns both shared counts', async () => { + const { moderationService, service, tx } = createCommandService(); + + await expect( + service.setPostReaction( + 'post-1', + { reaction: PostReactionType.THUMBS_DOWN }, + user, + '203.0.113.10', + ), + ).resolves.toEqual({ + postId: 'post-1', + viewerReaction: PostReactionType.THUMBS_DOWN, + thumbsUpCount: 2, + thumbsDownCount: 1, + }); + + expect(moderationService.decideForRequestActorBan).toHaveBeenCalledWith( + expect.objectContaining({ memberId: '1' }), + '203.0.113.10', + ); + expect(tx.postReaction.upsert).toHaveBeenCalledWith({ + where: { + postId_memberId: { postId: 'post-1', memberId: '1' }, + }, + create: { + postId: 'post-1', + memberId: '1', + reaction: PostReactionType.THUMBS_DOWN, + }, + update: { reaction: PostReactionType.THUMBS_DOWN }, + }); + expect(tx.postReaction.count).toHaveBeenCalledTimes(2); + expect(moderationService.decideForLockedTopicMutation).not.toHaveBeenCalled(); + }); + + it('removes a member reaction idempotently and returns a null viewer state', async () => { + const { service, tx } = createCommandService(); + tx.postReaction.deleteMany.mockResolvedValue({ count: 0 }); + tx.postReaction.count.mockResolvedValue(0); + + await expect( + service.removePostReaction('post-1', user), + ).resolves.toEqual({ + postId: 'post-1', + viewerReaction: null, + thumbsUpCount: 0, + thumbsDownCount: 0, + }); + expect(tx.postReaction.deleteMany).toHaveBeenCalledWith({ + where: { postId: 'post-1', memberId: '1' }, + }); + }); + + it('rejects reactions when post visibility is denied before persistence', async () => { + const { accessPolicyService, db, service, tx } = createCommandService(); + accessPolicyService.decideForPost.mockResolvedValue({ + canView: { allowed: false, reason: 'Insufficient forums access.' }, + }); + + await expect( + service.setPostReaction( + 'post-1', + { reaction: PostReactionType.THUMBS_UP }, + user, + ), + ).rejects.toThrow('Insufficient forums access.'); + expect(db.$transaction).not.toHaveBeenCalled(); + expect(tx.postReaction.upsert).not.toHaveBeenCalled(); + }); + + it('rejects machine callers because reactions belong to human members', async () => { + const { db, service } = createCommandService(); + + await expect( + service.removePostReaction('post-1', machineUser), + ).rejects.toThrow('Authenticated member token required.'); + expect(db.$transaction).not.toHaveBeenCalled(); + }); +}); + describe('ForumsCommandService member-targeted state commands', () => { const commandCases = [ { diff --git a/src/forums/forums-command.service.ts b/src/forums/forums-command.service.ts index e8d1249..3c972b9 100644 --- a/src/forums/forums-command.service.ts +++ b/src/forums/forums-command.service.ts @@ -10,6 +10,7 @@ import { JwtUser } from '../auth/jwt.service'; import { DbService } from '../db/db.service'; import { Post, + PostReactionType, Prisma, Topic, TopicReadState, @@ -19,11 +20,13 @@ import { CreatePostDto, CreateTopicDto, MemberTargetDto, + SetPostReactionDto, UpdatePostDto, UpdateTopicDto, } from './dto/forums-command.dto'; import { CreateTopicCommandResponseDto, + ForumPostReactionStateDto, ForumTopicCommandResponseDto, } from './dto/forums-command-response.dto'; import { @@ -113,7 +116,8 @@ export interface TopicWatchResult { } /** - * Command-side service for forum content, watch, and read-state mutations. + * Command-side service for forum content, reactions, watch, and read-state + * mutations. * * The service keeps transactional write shapes local while delegating * action-level authorization to the shared forums access policy and runtime @@ -680,6 +684,88 @@ export class ForumsCommandService { }); } + /** + * Adds or replaces the authenticated member's reaction on an active post. + * + * Reactions require post visibility and an unbanned human member, but remain + * available on locked topics because they do not change discussion content. + * + * @param postId Post id receiving the reaction. + * @param dto Requested thumbs-up or thumbs-down value. + * @param user Authenticated human member token payload. + * @param trustedClientIp Optional trusted client IP resolved at the HTTP boundary. + * @returns Resulting viewer reaction and aggregate post reaction counts. + * @throws UnauthorizedException when no authenticated human member is present. + * @throws ForbiddenException when runtime bans or inherited visibility deny access. + * @throws NotFoundException when the post or its active topic is missing or deleted. + */ + async setPostReaction( + postId: string, + dto: SetPostReactionDto, + user: JwtUser | undefined, + trustedClientIp?: string, + ): Promise { + const memberId = await this.authorizePostReaction( + postId, + user, + trustedClientIp, + ); + + return this.db.$transaction(async (tx) => { + await this.ensureMutablePost(tx, postId); + await tx.postReaction.upsert({ + where: { + postId_memberId: { postId, memberId }, + }, + create: { + postId, + memberId, + reaction: dto.reaction, + }, + update: { + reaction: dto.reaction, + }, + }); + + return this.buildPostReactionState(tx, postId, dto.reaction); + }); + } + + /** + * Removes the authenticated member's reaction from an active post. + * + * Removal is idempotent and remains available on locked topics. The response + * always reports a null viewer reaction plus current aggregate counts. + * + * @param postId Post id whose current-member reaction should be removed. + * @param user Authenticated human member token payload. + * @param trustedClientIp Optional trusted client IP resolved at the HTTP boundary. + * @returns Resulting null viewer reaction and aggregate post reaction counts. + * @throws UnauthorizedException when no authenticated human member is present. + * @throws ForbiddenException when runtime bans or inherited visibility deny access. + * @throws NotFoundException when the post or its active topic is missing or deleted. + */ + async removePostReaction( + postId: string, + user: JwtUser | undefined, + trustedClientIp?: string, + ): Promise { + const memberId = await this.authorizePostReaction( + postId, + user, + trustedClientIp, + ); + + return this.db.$transaction(async (tx) => { + await this.ensureMutablePost(tx, postId); + await tx.postReaction.deleteMany({ + where: { postId, memberId }, + }); + + return this.buildPostReactionState(tx, postId, null); + }); + } + /** * Adds an explicit watch for a member on a topic. * @@ -932,6 +1018,83 @@ export class ForumsCommandService { }; } + /** + * Authorizes a human member reaction against post visibility and runtime bans. + * + * @param postId Post id receiving a reaction command. + * @param user Authenticated token payload from request middleware. + * @param trustedClientIp Optional trusted client IP resolved at the HTTP boundary. + * @returns Authenticated member id used as the reaction owner. + * @throws UnauthorizedException when the caller is absent, M2M, or lacks a member id. + * @throws ForbiddenException when runtime bans or inherited visibility deny access. + * @throws NotFoundException when the post or owning topic is missing or deleted. + */ + private async authorizePostReaction( + postId: string, + user: JwtUser | undefined, + trustedClientIp?: string, + ): Promise { + const principal = this.requirePrincipal(user); + + if (principal.isMachine || !principal.memberId) { + throw new UnauthorizedException('Authenticated member token required.'); + } + + this.assertAllowed( + await this.moderationService.decideForRequestActorBan( + principal, + trustedClientIp, + ), + ); + const context = await this.topicContextService.loadPostContext( + postId, + principal, + ); + const postDecisions = await this.accessPolicyService.decideForPost( + principal, + context, + ); + + this.assertAllowed(postDecisions.canView); + + if (context.post.deletedAt) { + throw new NotFoundException('Post not found.'); + } + + return principal.memberId; + } + + /** + * Counts both post reaction types after a reaction command completes. + * + * @param tx Prisma transaction client containing the just-written state. + * @param postId Post id whose aggregate reactions should be counted. + * @param viewerReaction Current member reaction after the command. + * @returns Viewer state paired with current thumbs-up and thumbs-down counts. + * @throws Prisma errors when either aggregate count query fails. + */ + private async buildPostReactionState( + tx: Prisma.TransactionClient, + postId: string, + viewerReaction: PostReactionType | null, + ): Promise { + const [thumbsUpCount, thumbsDownCount] = await Promise.all([ + tx.postReaction.count({ + where: { postId, reaction: PostReactionType.THUMBS_UP }, + }), + tx.postReaction.count({ + where: { postId, reaction: PostReactionType.THUMBS_DOWN }, + }), + ]); + + return { + postId, + viewerReaction, + thumbsUpCount, + thumbsDownCount, + }; + } + /** * Builds the reusable forums principal required by policy checks. * diff --git a/src/forums/forums-notification-read.integration.spec.ts b/src/forums/forums-notification-read.integration.spec.ts index 390cd50..7d73714 100644 --- a/src/forums/forums-notification-read.integration.spec.ts +++ b/src/forums/forums-notification-read.integration.spec.ts @@ -2,7 +2,7 @@ import { INestApplication } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { Test } from '@nestjs/testing'; import * as request from 'supertest'; -import { Post, Topic } from '../../prisma/generated/client'; +import { Post, PostReactionType, Topic } from '../../prisma/generated/client'; import { DbService } from '../db/db.service'; import { ChallengeAccessService } from './challenge-access.service'; import { EventBusService } from './event-bus.service'; @@ -43,9 +43,16 @@ interface IpBanSeed { removedAt: Date | null; } +interface PostReactionSeed { + postId: string; + memberId: string; + reaction: PostReactionType; +} + interface SeededForumsData { topics: Topic[]; posts: Post[]; + postReactions: PostReactionSeed[]; topicClosures: TopicClosureSeed[]; topicWatches: TopicWatchSeed[]; topicReadStates: TopicReadStateSeed[]; @@ -139,27 +146,47 @@ function createSeededForumsDb(seed: SeededForumsData) { } if (queryText.includes('SELECT\n p.id')) { + const viewerMemberId = queryValueToString(values[0]); + return seed.posts .filter((post) => post.topicId === topicId) .sort(compareCreatedAtThenId) - .map((post) => ({ - id: post.id, - topicId: post.topicId, - parentType: post.parentType, - parentId: post.parentId, - authorMemberId: post.authorMemberId, - authorHandle: post.authorHandle, - authorPostsCount: seed.posts.filter( - (candidate) => - candidate.topicId === post.topicId && - candidate.authorMemberId === post.authorMemberId && - !candidate.deletedAt, - ).length, - content: post.content, - createdAt: post.createdAt, - updatedAt: post.updatedAt, - deletedAt: post.deletedAt, - })); + .map((post) => { + const reactions = seed.postReactions.filter( + (reaction) => reaction.postId === post.id, + ); + + return { + id: post.id, + topicId: post.topicId, + parentType: post.parentType, + parentId: post.parentId, + authorMemberId: post.authorMemberId, + authorHandle: post.authorHandle, + authorPostsCount: seed.posts.filter( + (candidate) => + candidate.topicId === post.topicId && + candidate.authorMemberId === post.authorMemberId && + !candidate.deletedAt, + ).length, + content: post.content, + createdAt: post.createdAt, + updatedAt: post.updatedAt, + deletedAt: post.deletedAt, + thumbsUpCount: reactions.filter( + (reaction) => + reaction.reaction === PostReactionType.THUMBS_UP, + ).length, + thumbsDownCount: reactions.filter( + (reaction) => + reaction.reaction === PostReactionType.THUMBS_DOWN, + ).length, + viewerReaction: + reactions.find( + (reaction) => reaction.memberId === viewerMemberId, + )?.reaction ?? null, + }; + }); } if (queryText.includes('SELECT EXISTS')) { @@ -258,6 +285,53 @@ function createSeededForumsDb(seed: SeededForumsData) { findUnique: (args: { where: { id: string } }) => seed.posts.find((post) => post.id === args.where.id) ?? null, }, + postReaction: { + upsert: (args: { + where: { + postId_memberId: { postId: string; memberId: string }; + }; + create: PostReactionSeed; + update: { reaction: PostReactionType }; + }) => { + const existing = seed.postReactions.find( + (reaction) => + reaction.postId === args.where.postId_memberId.postId && + reaction.memberId === args.where.postId_memberId.memberId, + ); + + if (existing) { + existing.reaction = args.update.reaction; + return existing; + } + + seed.postReactions.push(args.create); + return args.create; + }, + deleteMany: (args: { + where: { postId: string; memberId: string }; + }) => { + const index = seed.postReactions.findIndex( + (reaction) => + reaction.postId === args.where.postId && + reaction.memberId === args.where.memberId, + ); + + if (index < 0) { + return { count: 0 }; + } + + seed.postReactions.splice(index, 1); + return { count: 1 }; + }, + count: (args: { + where: { postId: string; reaction: PostReactionType }; + }) => + seed.postReactions.filter( + (reaction) => + reaction.postId === args.where.postId && + reaction.reaction === args.where.reaction, + ).length, + }, topicClosure: { findMany: (args: { where?: { @@ -637,6 +711,7 @@ describe('forums notification/read integration', () => { }), ], posts: [], + postReactions: [], topicClosures: [ { ancestorTopicId: 'parent-1', @@ -914,4 +989,69 @@ describe('forums notification/read integration', () => { }), ); }); + + it('shares post reaction counts while preserving each member viewer state', async () => { + seedData.posts.push(makePost({ topicId: 'parent-1', parentId: 'parent-1' })); + seedData.postReactions.push( + { + postId: 'post-1', + memberId: '1', + reaction: PostReactionType.THUMBS_UP, + }, + { + postId: 'post-1', + memberId: '2', + reaction: PostReactionType.THUMBS_DOWN, + }, + ); + + const memberOneDetail = await request(app.getHttpServer()) + .get('/topics/parent-1') + .set('x-member-id', '1') + .expect(200); + + expect(memberOneDetail.body.posts[0]).toEqual( + expect.objectContaining({ + thumbsUpCount: 1, + thumbsDownCount: 1, + viewerReaction: PostReactionType.THUMBS_UP, + }), + ); + + await request(app.getHttpServer()) + .put('/posts/post-1/reaction') + .set('x-member-id', '1') + .send({ reaction: PostReactionType.THUMBS_DOWN }) + .expect(200) + .expect({ + postId: 'post-1', + viewerReaction: PostReactionType.THUMBS_DOWN, + thumbsUpCount: 0, + thumbsDownCount: 2, + }); + + const memberTwoDetail = await request(app.getHttpServer()) + .get('/topics/parent-1') + .set('x-member-id', '2') + .expect(200); + + expect(memberTwoDetail.body.posts[0]).toEqual( + expect.objectContaining({ + thumbsUpCount: 0, + thumbsDownCount: 2, + viewerReaction: PostReactionType.THUMBS_DOWN, + }), + ); + + await request(app.getHttpServer()) + .delete('/posts/post-1/reaction') + .set('x-member-id', '1') + .expect(200) + .expect({ + postId: 'post-1', + viewerReaction: null, + thumbsUpCount: 0, + thumbsDownCount: 1, + }); + }); }); diff --git a/src/forums/forums-read-query.service.ts b/src/forums/forums-read-query.service.ts index 36571a1..4125b7f 100644 --- a/src/forums/forums-read-query.service.ts +++ b/src/forums/forums-read-query.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { Prisma } from '../../prisma/generated/client'; +import { PostReactionType, Prisma } from '../../prisma/generated/client'; import { DbService } from '../db/db.service'; /** @@ -58,6 +58,9 @@ export interface ForumsPostTreeRow { createdAt: Date; updatedAt: Date; deletedAt: Date | null; + thumbsUpCount: number; + thumbsDownCount: number; + viewerReaction: PostReactionType | null; } /** @@ -220,12 +223,14 @@ export class ForumsReadQueryService { * Fetches all posts for a topic, including soft-deleted placeholders. * * @param topicId Topic id whose posts should be returned. + * @param memberId Authenticated member id used to resolve viewer reaction state. * @param client Optional transaction client used to bind this read to a snapshot. - * @returns Post rows ordered by creation time for deterministic tree assembly. + * @returns Post rows with aggregate and viewer reactions, ordered for deterministic tree assembly. * @throws Prisma errors when the raw query fails. */ findTopicPostRows( topicId: string, + memberId: string | null, client: ForumsReadQueryClient = this.db, ): Promise { return client.$queryRaw(Prisma.sql` @@ -244,8 +249,25 @@ export class ForumsReadQueryService { p.content, p."createdAt", p."updatedAt", - p."deletedAt" + p."deletedAt", + reaction_stats."thumbsUpCount", + reaction_stats."thumbsDownCount", + reaction_stats."viewerReaction" FROM "Post" p + LEFT JOIN LATERAL ( + SELECT + COUNT(*) FILTER ( + WHERE post_reaction.reaction::text = 'THUMBS_UP' + )::integer AS "thumbsUpCount", + COUNT(*) FILTER ( + WHERE post_reaction.reaction::text = 'THUMBS_DOWN' + )::integer AS "thumbsDownCount", + MAX(post_reaction.reaction::text) FILTER ( + WHERE post_reaction."memberId" = CAST(${memberId} AS text) + ) AS "viewerReaction" + FROM "PostReaction" post_reaction + WHERE post_reaction."postId" = p.id + ) reaction_stats ON true WHERE p."topicId" = ${topicId} ORDER BY p."createdAt" ASC, p.id ASC `); @@ -302,7 +324,7 @@ export class ForumsReadQueryService { return null; } - const postRows = await this.findTopicPostRows(topicId, tx); + const postRows = await this.findTopicPostRows(topicId, memberId, tx); return { summaryRow, postRows }; }, diff --git a/src/forums/forums-read.service.ts b/src/forums/forums-read.service.ts index a269f26..8daa091 100644 --- a/src/forums/forums-read.service.ts +++ b/src/forums/forums-read.service.ts @@ -5,6 +5,7 @@ import { UnauthorizedException, } from '@nestjs/common'; import { JwtUser } from '../auth/jwt.service'; +import { PostReactionType } from '../../prisma/generated/client'; import { ForumsPostTreeNodeDto, ForumsTopicDetailDto, @@ -48,6 +49,9 @@ interface ForumsPostTreeNodeInternal { createdAt: Date; updatedAt: Date; deleted: boolean; + thumbsUpCount: number; + thumbsDownCount: number; + viewerReaction: PostReactionType | null; replies: ForumsPostTreeNodeInternal[]; subtreeLatestActivityAt: Date | null; } @@ -610,6 +614,9 @@ export class ForumsReadService { createdAt: row.createdAt, updatedAt: row.updatedAt, deleted, + thumbsUpCount: Number(row.thumbsUpCount), + thumbsDownCount: Number(row.thumbsDownCount), + viewerReaction: row.viewerReaction, replies: [], subtreeLatestActivityAt: deleted ? null : row.createdAt, }; @@ -693,6 +700,9 @@ export class ForumsReadService { createdAt: node.createdAt, updatedAt: node.updatedAt, deleted: node.deleted, + thumbsUpCount: node.thumbsUpCount, + thumbsDownCount: node.thumbsDownCount, + viewerReaction: node.viewerReaction, replies: node.replies.map((reply) => this.toPostTreeDto(reply)), }; } diff --git a/src/forums/posts.controller.ts b/src/forums/posts.controller.ts index 4527320..595cd4b 100644 --- a/src/forums/posts.controller.ts +++ b/src/forums/posts.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Delete, Param, Patch } from '@nestjs/common'; +import { Body, Controller, Delete, Param, Patch, Put } from '@nestjs/common'; import { ApiBadRequestResponse, ApiBearerAuth, @@ -22,17 +22,23 @@ import { FORUMS_SCOPE_DELETE_POST, FORUMS_SCOPE_UPDATE_POST, } from '../auth/scope-mappings'; -import { UpdatePostDto } from './dto/forums-command.dto'; -import { ForumPostCommandResponseDto } from './dto/forums-command-response.dto'; +import { + SetPostReactionDto, + UpdatePostDto, +} from './dto/forums-command.dto'; +import { + ForumPostCommandResponseDto, + ForumPostReactionStateDto, +} from './dto/forums-command-response.dto'; import { ForumsCommandService } from './forums-command.service'; /** * Controller for command-side post mutation routes. * - * The controller exposes only update and delete commands. Topic detail embeds - * post trees under `read:forums-topics`; `read:forums-posts` remains reserved - * for future post-specific read routes. Trusted client-IP context is forwarded - * as a string for runtime ban checks. + * The controller exposes update, delete, and human-member reaction commands. + * Topic detail embeds post trees under `read:forums-topics`; + * `read:forums-posts` remains reserved for future post-specific read routes. + * Trusted client-IP context is forwarded as a string for runtime ban checks. */ @ApiTags('Forums posts') @ApiBearerAuth() @@ -46,6 +52,97 @@ export class PostsController { */ constructor(private readonly commandService: ForumsCommandService) {} + /** + * Adds or switches the authenticated member's post reaction. + * + * @param postId Post id from the route. + * @param dto Thumbs-up or thumbs-down reaction value. + * @param user Authenticated human member token payload. + * @param trustedClientIp Optional trusted client IP resolved at the HTTP boundary. + * @returns The member's resulting reaction and shared aggregate counts. + * @throws UnauthorizedException when no authenticated human member is present. + * @throws ForbiddenException when an active ban or post visibility denies access. + * @throws BadRequestException when the reaction value is invalid. + * @throws NotFoundException when the post or active topic is missing or deleted. + */ + @Put(':postId/reaction') + @Roles(AUTHENTICATED_USER_ROLE) + @ApiOperation({ + summary: 'Set the current member forum post reaction', + description: + 'Human-member command route that adds a thumbs-up or thumbs-down reaction, or replaces the member\'s existing reaction with the requested value. Reactions require inherited post visibility and pass active member and trusted exact-IP ban checks. Locked topics remain reactable because reactions do not modify discussion content.', + }) + @ApiParam({ name: 'postId', description: 'Post id.' }) + @ApiResponse({ + status: 200, + description: 'Post reaction added or replaced.', + type: ForumPostReactionStateDto, + }) + @ApiBadRequestResponse({ description: 'Invalid reaction body.' }) + @ApiUnauthorizedResponse({ + description: 'Authenticated human member token required.', + }) + @ApiForbiddenResponse({ + description: 'Active forums ban or insufficient post visibility.', + }) + @ApiNotFoundResponse({ description: 'Post or active topic not found.' }) + setPostReaction( + @Param('postId') postId: string, + @Body() dto: SetPostReactionDto, + @CurrentUser() user?: JwtUser, + @ClientIp() trustedClientIp?: string, + ): Promise { + return this.commandService.setPostReaction( + postId, + dto, + user, + trustedClientIp, + ); + } + + /** + * Removes the authenticated member's current post reaction. + * + * @param postId Post id from the route. + * @param user Authenticated human member token payload. + * @param trustedClientIp Optional trusted client IP resolved at the HTTP boundary. + * @returns Null member reaction and the remaining shared aggregate counts. + * @throws UnauthorizedException when no authenticated human member is present. + * @throws ForbiddenException when an active ban or post visibility denies access. + * @throws NotFoundException when the post or active topic is missing or deleted. + */ + @Delete(':postId/reaction') + @Roles(AUTHENTICATED_USER_ROLE) + @ApiOperation({ + summary: 'Remove the current member forum post reaction', + description: + 'Human-member command route that idempotently removes the caller\'s reaction. It applies inherited post visibility plus active member and trusted exact-IP ban checks. Locked topics remain reactable because reactions do not modify discussion content.', + }) + @ApiParam({ name: 'postId', description: 'Post id.' }) + @ApiResponse({ + status: 200, + description: 'Post reaction removed or already absent.', + type: ForumPostReactionStateDto, + }) + @ApiUnauthorizedResponse({ + description: 'Authenticated human member token required.', + }) + @ApiForbiddenResponse({ + description: 'Active forums ban or insufficient post visibility.', + }) + @ApiNotFoundResponse({ description: 'Post or active topic not found.' }) + removePostReaction( + @Param('postId') postId: string, + @CurrentUser() user?: JwtUser, + @ClientIp() trustedClientIp?: string, + ): Promise { + return this.commandService.removePostReaction( + postId, + user, + trustedClientIp, + ); + } + /** * Updates an existing post. * diff --git a/src/main.ts b/src/main.ts index 3b7035c..3185704 100644 --- a/src/main.ts +++ b/src/main.ts @@ -37,7 +37,7 @@ async function bootstrap(): Promise { const swaggerConfig = new DocumentBuilder() .setTitle('Topcoder Forums API') .setDescription( - 'Topcoder forums API. The service exposes topic read routes protected by `read:forums-topics` plus transactional topic, post, watch, and read-state mutations with centralized forums authorization, runtime member/IP ban checks, locked-topic mutation restrictions, inherited topic restrictions, challenge/resource access checks, granular M2M scopes, and post-commit best-effort watch notification emails for created posts and child-topic starter posts. Dedicated moderation management routes let human administrators or M2M callers with `moderate:forums` lock/unlock topics and manage member or exact-IP bans; challenge copilots do not gain moderation-endpoint access. Topic detail embeds posts under `read:forums-topics`; `read:forums-posts` remains reserved for future post-specific reads. Health and readiness remain DB-only.', + 'Topcoder forums API. The service exposes topic read routes protected by `read:forums-topics` plus transactional topic, post, human-member post-reaction, watch, and read-state mutations with centralized forums authorization, runtime member/IP ban checks, locked-topic content-mutation restrictions, inherited topic restrictions, challenge/resource access checks, granular M2M scopes, and post-commit best-effort watch notification emails for created posts and child-topic starter posts. Dedicated moderation management routes let human administrators or M2M callers with `moderate:forums` lock/unlock topics and manage member or exact-IP bans; challenge copilots do not gain moderation-endpoint access. Topic detail embeds posts with shared reaction counts and current-member reaction state under `read:forums-topics`; `read:forums-posts` remains reserved for future post-specific reads. Health and readiness remain DB-only.', ) .setVersion('6.0') .addBearerAuth({