diff --git a/AGENTS.md b/AGENTS.md
index 42b80ca..4ce11a6 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -45,7 +45,7 @@ npm run test:smoke
## Docker lifecycle
-Start local services with `npm run docker:up` and stop them with `npm run docker:down`. This retains named volumes. The smoke test uses a separate Compose project and removes its volumes automatically. Run `docker compose down --volumes` only when intentionally resetting local PostgreSQL and AIStor data. Start the profile-gated application container with `docker compose --profile app up --build`.
+Start local services with `npm run docker:up`, apply migrations with `npm run prisma:deploy`, and optionally add local sample records with `npm run db:seed:examples`. Stop services with `npm run docker:down`; this retains named volumes. The example seed is limited to local database hosts. The smoke test uses a separate Compose project and removes its volumes automatically. Run `docker compose down --volumes` only when intentionally resetting local PostgreSQL and AIStor data. Start the profile-gated application container with `docker compose --profile app up --build`.
## Change checklist
diff --git a/README.md b/README.md
index 5dbab8f..9bc2e02 100644
--- a/README.md
+++ b/README.md
@@ -39,14 +39,22 @@ This repository contains the development foundation and initial App Router shell
npm run docker:up
```
-5. Run the available local checks.
+5. Apply the local database migrations and, if desired, insert three repeatable
+ example bounties with local SVG pictures.
+
+ ```sh
+ npm run prisma:deploy
+ npm run db:seed:examples
+ ```
+
+6. Run the available local checks.
```sh
npm run verify
npm run test:smoke
```
-6. Stop services when finished. `docker:down` preserves local volumes; use `docker compose down --volumes` only when you intentionally want to discard local database and object-storage data.
+7. Stop services when finished. `docker:down` preserves local volumes; use `docker compose down --volumes` only when you intentionally want to discard local database and object-storage data.
```sh
npm run docker:down
@@ -62,13 +70,15 @@ To install dependencies, start local services, and launch the development server
## Database migrations
-Prisma is configured for PostgreSQL and reads `DATABASE_URL` from `.env`. The initial account migration creates the `User` table with a unique email address and password hash. Once a model is approved, create and review a development migration with:
+Prisma is configured for PostgreSQL and reads `DATABASE_URL` from `.env`. The migrations create the account and bounty tables, including an optional picture reference on each bounty. Create and review a development migration with:
```sh
npm run prisma:migrate -- --name describe_the_change
```
-Use `npm run prisma:deploy` only in a controlled deployment workflow against an approved target—never against production from a workstation.
+Use `npm run prisma:deploy` to apply reviewed migrations to the local development database. For a remote deployment, run it only in a controlled workflow against the approved target—never against production from a workstation.
+
+`npm run db:seed:examples` inserts or refreshes three local example bounties and a demo poster. It refuses database hosts other than localhost or the local Compose service, and can be rerun without duplicating the examples.
## CI and GitHub configuration
diff --git a/app/posts/PostsList.tsx b/app/posts/PostsList.tsx
index b58d0a1..5c4ef59 100644
--- a/app/posts/PostsList.tsx
+++ b/app/posts/PostsList.tsx
@@ -1,20 +1,17 @@
-import styles from './posts.module.css'
+import Image from 'next/image'
-export type PostPreview = {
- id: string
- title: string
- location: string
-}
+import type { PostCardData } from './post-data'
+import styles from './posts.module.css'
type PostsListProps = {
- posts: PostPreview[]
+ posts: PostCardData[]
}
export function PostsList({ posts }: PostsListProps) {
if (posts.length === 0) {
return (
- No posts
+ No tasks are available right now.
)
}
@@ -23,13 +20,39 @@ export function PostsList({ posts }: PostsListProps) {
{posts.map((post) => (
-
-
{post.title}
-
{post.location}
-
-
- View details
-
+
+ {post.imageUrl ? (
+
+
+
+ ) : (
+
+ Community task
+
+ )}
+
+
{post.title}
+
{post.location}
+
+
+ More details
+
+
))}
diff --git a/app/posts/page.tsx b/app/posts/page.tsx
index 713a0e3..8d7a6d6 100644
--- a/app/posts/page.tsx
+++ b/app/posts/page.tsx
@@ -1,8 +1,10 @@
import { PostsList } from './PostsList'
-import { samplePosts } from './post-data'
+import { getPublicPostCards } from './post-data'
import styles from './posts.module.css'
-export default function PostsPage() {
+export default async function PostsPage() {
+ const posts = await getPublicPostCards()
+
return (
@@ -18,7 +20,7 @@ export default function PostsPage() {
diff --git a/app/posts/post-data.ts b/app/posts/post-data.ts
index af3af3d..2136982 100644
--- a/app/posts/post-data.ts
+++ b/app/posts/post-data.ts
@@ -1,24 +1,91 @@
-import type { PostPreview } from './PostsList'
+export type PostListingRecord = {
+ id: string
+ title: string
+ location: string
+ imageUrl: string | null
+ maximumVolunteers: number
+ currentVolunteers: number
+}
-export const samplePosts: PostPreview[] = [
- {
- id: 'cedar-grove-cleanup',
- title: 'Clean up Cedar Grove',
- location: 'Chico, CA',
- },
- {
- id: 'food-pantry-sorting',
- title: 'Sort food pantry donations',
- location: 'Downtown Chico, CA',
- },
- {
- id: 'community-garden',
- title: 'Water the community garden',
- location: 'South Chico, CA',
- },
- {
- id: 'trailhead-tidy',
- title: 'Tidy the trailhead',
- location: 'Upper Park, Chico, CA',
+export type PostCardData = Pick<
+ PostListingRecord,
+ 'id' | 'title' | 'location' | 'imageUrl'
+>
+
+export interface PostListingSource {
+ listPublicPosts(): Promise
+}
+
+const databaseSource: PostListingSource = {
+ async listPublicPosts() {
+ const { prisma } = await import('../../lib/prisma')
+ const bounties = await prisma.bounty.findMany({
+ where: {
+ status: 'OPEN',
+ deadline: { gt: new Date() },
+ },
+ orderBy: { createdAt: 'desc' },
+ select: {
+ id: true,
+ title: true,
+ locationLabel: true,
+ imageUrl: true,
+ maxVolunteers: true,
+ _count: {
+ select: {
+ volunteerAttendances: {
+ where: { status: 'JOINED' },
+ },
+ },
+ },
+ },
+ })
+
+ return bounties.map((bounty) => ({
+ id: bounty.id,
+ title: bounty.title,
+ location: bounty.locationLabel,
+ imageUrl: bounty.imageUrl,
+ maximumVolunteers: bounty.maxVolunteers,
+ currentVolunteers: bounty._count.volunteerAttendances,
+ }))
},
-]
+}
+
+/**
+ * Keep the database query on the server and return only fields needed by a
+ * public post card.
+ */
+export async function getPublicPostCards(
+ source: PostListingSource = databaseSource,
+): Promise {
+ const records = await source.listPublicPosts()
+
+ return records
+ .filter(
+ (record) =>
+ Number.isInteger(record.maximumVolunteers) &&
+ record.maximumVolunteers > 0 &&
+ Number.isInteger(record.currentVolunteers) &&
+ record.currentVolunteers >= 0 &&
+ record.currentVolunteers < record.maximumVolunteers,
+ )
+ .map(({ id, title, location, imageUrl }) => ({
+ id,
+ title,
+ location,
+ imageUrl: getSafeImageUrl(imageUrl),
+ }))
+}
+
+function getSafeImageUrl(imageUrl: string | null): string | null {
+ if (!imageUrl) return null
+ if (imageUrl.startsWith('/') && !imageUrl.startsWith('//')) return imageUrl
+
+ try {
+ const parsedImageUrl = new URL(imageUrl)
+ return parsedImageUrl.protocol === 'https:' ? imageUrl : null
+ } catch {
+ return null
+ }
+}
diff --git a/app/posts/posts.module.css b/app/posts/posts.module.css
index 920ff9d..9c95f16 100644
--- a/app/posts/posts.module.css
+++ b/app/posts/posts.module.css
@@ -44,35 +44,56 @@
}
.listViewport {
- height: clamp(19rem, 58dvh, 30rem);
- overflow-y: auto;
border-top: 1px solid var(--ink);
- border-bottom: 1px solid var(--ink);
- scrollbar-color: var(--accent) var(--canvas);
}
.postsList {
display: grid;
- gap: 0.75rem;
+ grid-template-columns: minmax(0, 1fr);
+ gap: 1rem;
margin: 0;
- padding: 0.75rem 0;
+ padding: 1rem 0 0;
list-style: none;
}
.postCard {
- display: flex;
- align-items: end;
- justify-content: space-between;
- gap: 1rem;
- min-height: 7.5rem;
- padding: 1rem;
+ min-width: 0;
border: 1px solid var(--ink);
background: #fffefa;
}
+.postContent {
+ display: grid;
+ grid-template-rows: auto 1fr auto;
+ height: 100%;
+}
+
+.postImage {
+ position: relative;
+ aspect-ratio: 16 / 9;
+ overflow: hidden;
+ background: var(--accent-soft);
+}
+
+.postImageAsset {
+ object-fit: cover;
+}
+
+.postImageFallback {
+ display: grid;
+ place-items: center;
+ color: var(--muted);
+ font-family: Georgia, 'Times New Roman', serif;
+ font-size: 1.25rem;
+}
+
+.postInfo {
+ padding: 1rem 1rem 0.75rem;
+}
+
.postCard h2 {
margin: 0;
- font-size: clamp(1.25rem, 4vw, 1.75rem);
+ font-size: clamp(1.25rem, 3vw, 1.75rem);
}
.postCard p {
@@ -80,16 +101,25 @@
color: var(--muted);
}
-.postCard button {
- flex: 0 0 auto;
+.detailsButton {
+ justify-self: start;
+ min-height: 2.75rem;
+ margin: 0 1rem 1rem;
padding: 0.5rem 0.75rem;
- white-space: nowrap;
+ border: 1px solid var(--ink);
+ border-radius: 0;
+ color: var(--ink);
+ background: var(--canvas);
+ font: inherit;
+ font-weight: 700;
+ cursor: not-allowed;
+ opacity: 0.75;
}
.emptyState {
display: grid;
- height: 100%;
- margin: 0;
+ min-height: 12rem;
+ margin: 1rem 0 0;
place-items: center;
color: var(--muted);
}
@@ -102,4 +132,9 @@
.postsBoard {
padding: 1.5rem;
}
+
+ .postsList {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 1.25rem;
+ }
}
diff --git a/docs/decisions/ADR-002-capacity-based-volunteer-attendance.md b/docs/decisions/ADR-002-capacity-based-volunteer-attendance.md
new file mode 100644
index 0000000..d71a8a1
--- /dev/null
+++ b/docs/decisions/ADR-002-capacity-based-volunteer-attendance.md
@@ -0,0 +1,59 @@
+# ADR-002: Model bounty attendance as capacity-based volunteer records
+
+## Status
+
+Accepted
+
+## Date
+
+2026-10-14
+
+## Context
+
+Sidecause originally modeled a bounty as a single-member claim. The posts
+experience now requires a scheduled task with a minimum and maximum number of
+volunteers, a list of attendees, and required or recommended skills and
+equipment. The poster's contact information must be available to volunteers
+who have joined the post, but never to visitors or other signed-in members.
+
+## Decision
+
+Store attendance in a relation between a bounty and a user, rather than a
+single claimant field or a list encoded in the bounty record. Enforce a unique
+member-and-bounty attendance record and guard joins transactionally against
+`maxVolunteers`.
+
+Each bounty stores one scheduled timestamp and retains its separate joining
+deadline. It has a positive `maxVolunteers` value and a non-negative
+`payPerVolunteer` amount. Skills and equipment are separate child
+relations, with each requirement marked `REQUIRED` or `RECOMMENDED`.
+
+A bounty is `OPEN` while a place remains and `FULL` when its maximum attendance
+is reached. A joined volunteer can withdraw; this returns a full bounty to
+open and revokes contact access. Only the poster can complete the task. The
+poster’s display name and account email are projected only to authenticated
+volunteers with active attendance on that bounty.
+
+## Alternatives considered
+
+### Keep one claimant and add a capacity field
+
+This would leave no relational record for the other attendees and could not
+reliably enforce or query per-user attendance.
+
+### Store attendee identifiers in an array on the bounty
+
+This weakens relational integrity, makes member deletion and joins harder to
+reason about, and complicates the unique-attendance constraint.
+
+### Make poster contact public
+
+Public email disclosure conflicts with the privacy boundary in the product
+contract and exposes posters to unsolicited contact.
+
+## Consequences
+
+- The Bounty schema and lifecycle API contract require a reviewed migration.
+- Join and withdrawal operations require transactional capacity handling.
+- Public, member, and attendee response projections must be tested separately.
+- The new `FULL` state is public; cancelled and expired bounties remain hidden.
diff --git a/docs/implementation-plan.md b/docs/implementation-plan.md
index 6dca023..af46e67 100644
--- a/docs/implementation-plan.md
+++ b/docs/implementation-plan.md
@@ -4,8 +4,8 @@
Implement Sidecause in small, testable vertical slices. The product contract in
[`product-spec.md`](product-spec.md) is the source of truth. Each schema and
-API task must preserve the documented public/hidden status boundary and the
-single-volunteer claim invariant.
+API task must preserve the documented public/hidden status boundary, capacity
+limit, per-volunteer pay, and attendee-contact privacy boundary.
## Architecture decisions
@@ -13,7 +13,8 @@ single-volunteer claim invariant.
- Use Auth.js with email-and-password credentials and Prisma/PostgreSQL-backed
user records. Passwords are stored only as secure hashes.
- Expose REST-style route handlers with a single structured error shape.
-- Use transactions or an equivalent guarded conditional update for claims.
+- Use transactions or an equivalent guarded conditional update for joins so
+ concurrent requests cannot exceed a bounty's maximum volunteer capacity.
## Task list
@@ -58,14 +59,17 @@ Prisma migration.
### Phase 2: Publish and browse bounties
-#### Task 3: Define and migrate the bounty domain
+#### Task 3: Define and migrate the scheduled, capacity-based bounty domain
**Acceptance criteria:**
-- [ ] The schema represents locations, deadlines, lifecycle status, poster,
- optional claimant, completion, verification, and cancellation reason.
-- [ ] The schema makes a single claimant unambiguous and supports future
- additive volunteer capacity.
+- [ ] The schema represents locations, scheduled date/time, joining deadline,
+ maximum capacity, per-volunteer pay, lifecycle status, poster, completion, verification, and
+ cancellation reason.
+- [ ] A volunteer-attendance relation makes one attendance record per member
+ and bounty unambiguous, and supports an attendee list.
+- [ ] Requirement relations store distinct skills and equipment with a
+ `REQUIRED` or `RECOMMENDED` designation.
- [ ] A migration is reviewed and applies to local PostgreSQL.
**Verify:** `npm run prisma:validate`; run the reviewed development migration;
@@ -76,15 +80,19 @@ integration tests for persistence constraints.
**Likely files:** `prisma/schema.prisma`, `prisma/migrations/*`, domain types,
integration tests.
-#### Task 4: Create and list public bounties
+#### Task 4: Create and list public scheduled bounties
**Acceptance criteria:**
-- [ ] An authenticated member can create a valid open bounty.
-- [ ] Visitors can browse a paginated list of `OPEN`, `CLAIMED`, and
+- [ ] An authenticated member can create a valid open bounty with a schedule,
+ maximum capacity, per-volunteer pay, and skill/equipment requirements.
+- [ ] Visitors can browse a paginated list of `OPEN`, `FULL`, and
`FINISHED` bounties.
- [ ] Cancelled and expired bounties never appear in public list or detail
responses.
+- [ ] Public responses never include the poster's email; it is included only
+ for authenticated volunteers with active attendance on that bounty.
+ Withdrawal immediately revokes access.
**Verify:** Unit tests for input schemas and expiry calculation; integration
tests for API contracts; browser test for browse and create flows.
@@ -100,34 +108,39 @@ pages and components, unit/integration/e2e tests.
- [ ] Validation and authorization errors use the specified shape.
- [ ] `npm run verify` and relevant integration/browser tests pass.
-### Phase 3: Claim and completion lifecycle
+### Phase 3: Volunteer attendance and completion lifecycle
-#### Task 5: Claim and withdraw safely
+#### Task 5: Join and withdraw safely
**Acceptance criteria:**
-- [ ] Exactly one member can claim an open, unexpired bounty.
-- [ ] A second or late claim returns `409` and does not modify ownership.
-- [ ] The claimant can withdraw, returning the bounty to `OPEN`.
+- [ ] A member can immediately join an open, unexpired bounty while capacity
+ remains.
+- [ ] A duplicate, late, or over-capacity join returns `409` and does not
+ exceed `maxVolunteers`.
+- [ ] A joined volunteer can withdraw; withdrawing from a full bounty returns
+ it to `OPEN` and revokes access to the poster's contact information.
-**Verify:** Concurrent integration test for claim attempts; browser test for
-claim and withdrawal.
+**Verify:** Concurrent integration test for last-slot join attempts; browser
+test for join and withdrawal.
**Dependencies:** Task 4.
-**Likely files:** claim service, claim route handlers, bounty detail UI, tests.
+**Likely files:** attendance service, volunteer route handlers, bounty detail
+UI, tests.
#### Task 6: Finish, verify, and cancel
**Acceptance criteria:**
-- [ ] Only the claimant can finish a claimed bounty, without proof submission.
+- [ ] Only the poster can finish an open or full bounty, without proof
+ submission.
- [ ] Only the poster can optionally verify a finished bounty.
-- [ ] Only the poster can cancel an open or claimed bounty with an optional
+- [ ] Only the poster can cancel an open or full bounty with an optional
reason.
**Verify:** Authorization and transition integration tests; browser test for
-the full poster/claimant workflow.
+the full poster/volunteer workflow.
**Dependencies:** Task 5.
@@ -144,12 +157,13 @@ the full poster/claimant workflow.
## Risks and mitigations
-| Risk | Impact | Mitigation |
-| ------------------------------------ | ---------------------- | ---------------------------------------------------------------------------------------------------------- |
-| Two members claim simultaneously | High | Use a transaction/conditional status update and test concurrent requests. |
-| Unverified email plus no recovery | High user-support cost | Make the limitation explicit in registration UI; revisit verification/recovery before public launch. |
-| Inappropriate or unsafe public posts | High | Moderation is intentionally deferred; do not launch broadly until a reporting/moderation decision is made. |
-| Deadlines depend on client clocks | Medium | Compare deadlines on the server and use one UTC timestamp representation. |
+| Risk | Impact | Mitigation |
+| ------------------------------------ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------- |
+| Concurrent joins exceed capacity | High | Use a transaction/conditional status update and test simultaneous last-slot joins. |
+| Poster contact information leaks | High | Project public, poster, active-attendee, and withdrawn-attendee response shapes separately; test each access boundary. |
+| Unverified email plus no recovery | High user-support cost | Make the limitation explicit in registration UI; revisit verification/recovery before public launch. |
+| Inappropriate or unsafe public posts | High | Moderation is intentionally deferred; do not launch broadly until a reporting/moderation decision is made. |
+| Deadlines depend on client clocks | Medium | Compare deadlines on the server and use one UTC timestamp representation. |
## Approval gates
diff --git a/docs/post-listing-data-contract.md b/docs/post-listing-data-contract.md
new file mode 100644
index 0000000..440da99
--- /dev/null
+++ b/docs/post-listing-data-contract.md
@@ -0,0 +1,50 @@
+# Post Listing Data Contract
+
+The Posts page reads through a server-side `PostListingSource` in
+[`app/posts/post-data.ts`](../app/posts/post-data.ts). Its default source queries
+the Prisma `Bounty` table and returns open bounties whose signup deadline has
+not passed and whose capacity is not full. The page remains independent of
+Prisma and receives only card-safe fields.
+
+## Listing fields
+
+`listPublicPosts()` returns records with:
+
+| Field | Type | Purpose |
+| ------------------- | -------------------- | ----------------------------------------- |
+| `id` | string | Stable post identifier |
+| `title` | string | Card title |
+| `location` | string | Human-readable task location |
+| `imageUrl` | string or `null` | Same-origin path or HTTPS URL |
+| `maximumVolunteers` | positive integer | Capacity; used on the future details page |
+| `currentVolunteers` | non-negative integer | Number of active signups |
+
+The database query counts only `JOINED` volunteer attendances and omits a
+record when that count reaches `maxVolunteers`. The public card data contains
+only `id`, `title`, `location`, and `imageUrl`. A missing or invalid picture
+reference uses the neutral image fallback.
+Uploader contact details, signup identities, and other private fields must not
+be returned from the listing source or exposed to the Posts page.
+
+Picture files should be stored in object storage, with the database holding a
+storage key or URL. The adapter should resolve storage keys to an HTTPS URL
+before returning listing records. The current server boundary accepts only
+same-origin paths or HTTPS URLs and falls back to a neutral image block for
+missing or invalid values.
+
+## Future details page fields
+
+The collaborator's schema should also support the later details page with:
+
+- Event date and time.
+- Description summary.
+- Pay per volunteer.
+- Required skills and equipment.
+- Maximum volunteer capacity.
+- Volunteer signups and their public display names.
+- Uploader public display name and private contact information.
+
+Signing up is immediate. A volunteer who has signed up may see the uploader's
+contact information; visitors and members who have not signed up may not. Keep
+that authorization check in the server-side details read path when it is built.
+The Posts listing itself has no signup action or details navigation yet.
diff --git a/docs/product-spec.md b/docs/product-spec.md
index ebc658b..ea9ebc4 100644
--- a/docs/product-spec.md
+++ b/docs/product-spec.md
@@ -3,20 +3,21 @@
## Objective
Sidecause is a public community-service bounty board. Anyone can browse active
-or completed opportunities. Signed-in members can post an opportunity, claim
+or completed opportunities. Signed-in members can post an opportunity, join
one, and manage the resulting volunteer work.
-The first release is deliberately small: a bounty is a single-volunteer,
-unpaid opportunity. It must make it easy to discover a project, commit to it,
-and show that it was finished.
+The first release is deliberately small: a bounty is an unpaid, scheduled
+opportunity for a bounded group of volunteers. It must make it easy to
+discover a project, join it while places remain, and show that it was
+finished.
## Users and access
-| User | Can do |
-| ---------------- | ---------------------------------------------------------------------------------------- |
-| Visitor | Browse `OPEN`, `CLAIMED`, and `FINISHED` bounties. |
-| Signed-in member | All visitor actions plus create, claim, withdraw from, and finish bounties. |
-| Bounty poster | All member actions plus cancel and optionally verify completion of bounties they posted. |
+| User | Can do |
+| ---------------- | ----------------------------------------------------------------------------- |
+| Visitor | Browse `OPEN`, `FULL`, and `FINISHED` bounties. |
+| Signed-in member | All visitor actions plus create, join, and withdraw from bounties. |
+| Bounty poster | All member actions plus finish, cancel, and optionally verify their bounties. |
Authentication uses an email address, password, and public display name. Email
verification, password recovery, social sign-in, and moderation are out of
@@ -26,25 +27,32 @@ v1.
## Bounty lifecycle
```text
-OPEN --claim--> CLAIMED --finish--> FINISHED
- ^ |
- |---withdraw------|
+OPEN --join until full--> FULL
+ ^ |
+ |-------withdraw--------|
-OPEN or CLAIMED --cancel--> CANCELLED
-OPEN --deadline passes--> EXPIRED
+OPEN or FULL --poster finishes--> FINISHED
+
+OPEN or FULL --cancel--> CANCELLED
+OPEN or FULL --deadline passes--> EXPIRED
```
-- Only one member may claim an `OPEN` bounty.
-- Finishing is immediate and requires no note, photograph, or poster approval.
+- A member may join an `OPEN` bounty immediately while its attendance count is
+ below `maxVolunteers`; the join changes it to `FULL` when the count reaches
+ that limit.
+- A joined member may withdraw. Withdrawing from a `FULL` bounty returns it to
+ `OPEN`.
+- Only the poster may finish a bounty. Finishing requires no note, photograph,
+ or attendee approval.
- A poster may optionally verify a finished bounty. Verification is separate
from its status and never blocks finishing.
-- A poster may cancel an `OPEN` or `CLAIMED` bounty, optionally supplying a
+- A poster may cancel an `OPEN` or `FULL` bounty, optionally supplying a
cancellation reason.
- Published bounties cannot otherwise be edited.
-- Public listings and public detail pages expose only `OPEN`, `CLAIMED`, and
+- Public listings and public detail pages expose only `OPEN`, `FULL`, and
`FINISHED` bounties. `CANCELLED` and `EXPIRED` bounties are not public.
- Expiry is determined server-side from the deadline. An expired bounty cannot
- be claimed.
+ be joined.
## Bounty data
@@ -53,14 +61,26 @@ Each bounty has:
- A required title and description.
- A required human-readable location label, such as a neighbourhood or a
specific address.
+- An optional picture reference. Store the image file in object storage and
+ keep its storage key or URL on the bounty.
- Optional precise latitude and longitude, supplied together when the location
is specific enough for a map point.
-- A required deadline. A bounty expires after it.
-- The poster, optional claimant, status, creation time, finish time, optional
- verification time, and optional cancellation reason.
-
-Display names are public where a poster or claimant is shown. Email addresses,
-password hashes, and authentication/session data are never public.
+- A required scheduled date and time, plus a required deadline for joining. A
+ bounty expires after its deadline; its scheduled time is task information,
+ not an automatic lifecycle transition.
+- A required positive maximum volunteer count.
+- A non-negative monetary amount paid per volunteer, stored with two decimal
+ places.
+- Zero or more named skill requirements and equipment requirements, each
+ marked `REQUIRED` or `RECOMMENDED`.
+- The poster, zero or more attending volunteers, status, creation time, finish
+ time, optional verification time, and optional cancellation reason.
+
+Display names are public where a poster or attendee is shown. The poster's
+display name and account email are available only to authenticated volunteers
+with active attendance on that bounty; withdrawing immediately revokes access.
+Email addresses, password hashes, and
+authentication/session data are never included in public responses.
## Application boundary and API contract
@@ -82,23 +102,24 @@ All API errors use this response shape:
Validation failures return `422`; unauthenticated requests `401`; unauthorized
requests `403`; missing or non-public resources `404`; and lifecycle conflicts
-(such as a second simultaneous claim) `409`. Internal errors never reveal
+(such as simultaneous attempts to take the final place) `409`. Internal errors never reveal
implementation details.
-| Operation | Contract |
-| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `GET /api/bounties` | Public, paginated list of public statuses. Supports `page`, `pageSize`, `status`, and location filtering defined during implementation. Returns `{ data, pagination }`. |
-| `POST /api/bounties` | Authenticated creation. Accepts title, description, location, optional coordinates, and deadline. Returns the created bounty with `201`. |
-| `GET /api/bounties/:id` | Public only for a public-status bounty; otherwise returns `404`. |
-| `POST /api/bounties/:id/claims` | Authenticated. Atomically claims an open, unexpired bounty for the current user. |
-| `DELETE /api/bounties/:id/claims/me` | Claimant only. Releases the claim and returns the bounty to `OPEN`. |
-| `POST /api/bounties/:id/completion` | Claimant only. Marks the bounty `FINISHED`. |
-| `POST /api/bounties/:id/verification` | Poster only. Marks a finished bounty verified. |
-| `POST /api/bounties/:id/cancellation` | Poster only. Cancels an open or claimed bounty; body may include `reason`. |
+| Operation | Contract |
+| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `GET /api/bounties` | Public, paginated list of public statuses. Supports `page`, `pageSize`, `status`, and location filtering defined during implementation. Returns `{ data, pagination }`. |
+| `POST /api/bounties` | Authenticated creation. Accepts title, description, location, optional coordinates, schedule and deadline, maximum capacity, per-volunteer pay, and requirements. Returns the created bounty with `201`. |
+| `GET /api/bounties/:id` | Public only for a public-status bounty; otherwise returns `404`. Public responses never contain poster contact information. |
+| `GET /api/bounties/:id/poster-contact` | Authenticated active attendee only. Returns the poster's permitted contact information. |
+| `POST /api/bounties/:id/volunteers` | Authenticated. Atomically joins an open, unexpired bounty when capacity remains. |
+| `DELETE /api/bounties/:id/volunteers/me` | Joined volunteer only. Withdraws and returns a full bounty to `OPEN`. |
+| `POST /api/bounties/:id/completion` | Poster only. Marks the bounty `FINISHED`. |
+| `POST /api/bounties/:id/verification` | Poster only. Marks a finished bounty verified. |
+| `POST /api/bounties/:id/cancellation` | Poster only. Cancels an open or full bounty; body may include `reason`. |
Inputs are validated at route-handler boundaries. Internal services receive
-trusted, typed inputs. State-changing operations must be transactional so two
-users cannot both claim the same bounty.
+trusted, typed inputs. State-changing operations must be transactional so
+concurrent joins cannot exceed `maxVolunteers`.
## Commands
@@ -138,19 +159,18 @@ docs/ Product specification, decisions, and implementation plans
## Success criteria
- A visitor can view a paginated public list and public detail pages for open,
- claimed, and finished bounties.
-- A member can register, sign in, create a bounty, and claim one open bounty.
-- A claimant can withdraw or finish their own claim; concurrent claims do not
- assign two volunteers.
-- A poster can cancel their own open or claimed bounty and optionally verify a
- finished one.
+ full, and finished bounties.
+- A member can register, sign in, create a bounty, and join one open bounty
+ while capacity remains.
+- A joined volunteer can withdraw; concurrent joins never exceed a bounty's
+ maximum volunteer count.
+- A poster can finish or cancel their own open or full bounty and optionally
+ verify a finished one.
- All invalid or unauthorized requests follow the documented error contract.
## Explicitly deferred
- Payments and experience-point rewards.
-- Multiple volunteers per bounty. A future additive `volunteerCapacity` field
- may extend the one-volunteer model.
- Bounty editing, proof uploads, comments, reporting, and moderation.
- Email verification, password recovery, social sign-in, and organization
accounts.
diff --git a/generated/prisma/browser.ts b/generated/prisma/browser.ts
new file mode 100644
index 0000000..2cfde9b
--- /dev/null
+++ b/generated/prisma/browser.ts
@@ -0,0 +1,44 @@
+
+/* !!! This is code generated by Prisma. Do not edit directly. !!! */
+/* eslint-disable */
+// biome-ignore-all lint: generated file
+// @ts-nocheck
+/*
+ * This file should be your main import to use Prisma-related types and utilities in a browser.
+ * Use it to get access to models, enums, and input types.
+ *
+ * This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
+ * See `client.ts` for the standard, server-side entry point.
+ *
+ * 🟢 You can import this file directly.
+ */
+
+import * as Prisma from './internal/prismaNamespaceBrowser'
+export { Prisma }
+export * as $Enums from './enums'
+export * from './enums';
+/**
+ * Model User
+ *
+ */
+export type User = Prisma.UserModel
+/**
+ * Model Bounty
+ *
+ */
+export type Bounty = Prisma.BountyModel
+/**
+ * Model BountyVolunteer
+ *
+ */
+export type BountyVolunteer = Prisma.BountyVolunteerModel
+/**
+ * Model BountySkillRequirement
+ *
+ */
+export type BountySkillRequirement = Prisma.BountySkillRequirementModel
+/**
+ * Model BountyEquipmentRequirement
+ *
+ */
+export type BountyEquipmentRequirement = Prisma.BountyEquipmentRequirementModel
diff --git a/generated/prisma/client.ts b/generated/prisma/client.ts
new file mode 100644
index 0000000..41d5b1a
--- /dev/null
+++ b/generated/prisma/client.ts
@@ -0,0 +1,68 @@
+
+/* !!! This is code generated by Prisma. Do not edit directly. !!! */
+/* eslint-disable */
+// biome-ignore-all lint: generated file
+// @ts-nocheck
+/*
+ * This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
+ * If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
+ *
+ * 🟢 You can import this file directly.
+ */
+
+import * as process from 'node:process'
+import * as path from 'node:path'
+import { fileURLToPath } from 'node:url'
+globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url))
+
+import * as runtime from "@prisma/client/runtime/client"
+import * as $Enums from "./enums"
+import * as $Class from "./internal/class"
+import * as Prisma from "./internal/prismaNamespace"
+
+export * as $Enums from './enums'
+export * from "./enums"
+/**
+ * ## Prisma Client
+ *
+ * Type-safe database client for TypeScript
+ * @example
+ * ```
+ * const prisma = new PrismaClient({
+ * adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL })
+ * })
+ * // Fetch zero or more Users
+ * const users = await prisma.user.findMany()
+ * ```
+ *
+ * Read more in our [docs](https://pris.ly/d/client).
+ */
+export const PrismaClient = $Class.getPrismaClientClass()
+export type PrismaClient = $Class.PrismaClient
+export { Prisma }
+
+/**
+ * Model User
+ *
+ */
+export type User = Prisma.UserModel
+/**
+ * Model Bounty
+ *
+ */
+export type Bounty = Prisma.BountyModel
+/**
+ * Model BountyVolunteer
+ *
+ */
+export type BountyVolunteer = Prisma.BountyVolunteerModel
+/**
+ * Model BountySkillRequirement
+ *
+ */
+export type BountySkillRequirement = Prisma.BountySkillRequirementModel
+/**
+ * Model BountyEquipmentRequirement
+ *
+ */
+export type BountyEquipmentRequirement = Prisma.BountyEquipmentRequirementModel
diff --git a/generated/prisma/commonInputTypes.ts b/generated/prisma/commonInputTypes.ts
new file mode 100644
index 0000000..6092e78
--- /dev/null
+++ b/generated/prisma/commonInputTypes.ts
@@ -0,0 +1,536 @@
+
+/* !!! This is code generated by Prisma. Do not edit directly. !!! */
+/* eslint-disable */
+// biome-ignore-all lint: generated file
+// @ts-nocheck
+/*
+ * This file exports various common sort, input & filter types that are not directly linked to a particular model.
+ *
+ * 🟢 You can import this file directly.
+ */
+
+import type * as runtime from "@prisma/client/runtime/client"
+import * as $Enums from "./enums"
+import type * as Prisma from "./internal/prismaNamespace"
+
+
+export type StringFilter<$PrismaModel = never> = {
+ equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
+ notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
+ lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ mode?: Prisma.QueryMode
+ not?: Prisma.NestedStringFilter<$PrismaModel> | string
+}
+
+export type DateTimeFilter<$PrismaModel = never> = {
+ equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
+ notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
+ lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
+}
+
+export type StringWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
+ notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
+ lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ mode?: Prisma.QueryMode
+ not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedStringFilter<$PrismaModel>
+ _max?: Prisma.NestedStringFilter<$PrismaModel>
+}
+
+export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
+ notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
+ lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedDateTimeFilter<$PrismaModel>
+ _max?: Prisma.NestedDateTimeFilter<$PrismaModel>
+}
+
+export type StringNullableFilter<$PrismaModel = never> = {
+ equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
+ in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
+ notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
+ lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ mode?: Prisma.QueryMode
+ not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
+}
+
+export type DecimalNullableFilter<$PrismaModel = never> = {
+ equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null
+ in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
+ notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
+ lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDecimalNullableFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
+}
+
+export type IntFilter<$PrismaModel = never> = {
+ equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
+ notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
+ lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedIntFilter<$PrismaModel> | number
+}
+
+export type DecimalFilter<$PrismaModel = never> = {
+ equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel>
+ notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel>
+ lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDecimalFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string
+}
+
+export type EnumBountyStatusFilter<$PrismaModel = never> = {
+ equals?: $Enums.BountyStatus | Prisma.EnumBountyStatusFieldRefInput<$PrismaModel>
+ in?: $Enums.BountyStatus[] | Prisma.ListEnumBountyStatusFieldRefInput<$PrismaModel>
+ notIn?: $Enums.BountyStatus[] | Prisma.ListEnumBountyStatusFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumBountyStatusFilter<$PrismaModel> | $Enums.BountyStatus
+}
+
+export type DateTimeNullableFilter<$PrismaModel = never> = {
+ equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
+ in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
+ notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
+ lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null
+}
+
+export type SortOrderInput = {
+ sort: Prisma.SortOrder
+ nulls?: Prisma.NullsOrder
+}
+
+export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
+ in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
+ notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
+ lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ mode?: Prisma.QueryMode
+ not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
+ _count?: Prisma.NestedIntNullableFilter<$PrismaModel>
+ _min?: Prisma.NestedStringNullableFilter<$PrismaModel>
+ _max?: Prisma.NestedStringNullableFilter<$PrismaModel>
+}
+
+export type DecimalNullableWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null
+ in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
+ notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
+ lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDecimalNullableWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
+ _count?: Prisma.NestedIntNullableFilter<$PrismaModel>
+ _avg?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
+ _sum?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
+ _min?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
+ _max?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
+}
+
+export type IntWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
+ notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
+ lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _avg?: Prisma.NestedFloatFilter<$PrismaModel>
+ _sum?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedIntFilter<$PrismaModel>
+ _max?: Prisma.NestedIntFilter<$PrismaModel>
+}
+
+export type DecimalWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel>
+ notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel>
+ lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDecimalWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _avg?: Prisma.NestedDecimalFilter<$PrismaModel>
+ _sum?: Prisma.NestedDecimalFilter<$PrismaModel>
+ _min?: Prisma.NestedDecimalFilter<$PrismaModel>
+ _max?: Prisma.NestedDecimalFilter<$PrismaModel>
+}
+
+export type EnumBountyStatusWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: $Enums.BountyStatus | Prisma.EnumBountyStatusFieldRefInput<$PrismaModel>
+ in?: $Enums.BountyStatus[] | Prisma.ListEnumBountyStatusFieldRefInput<$PrismaModel>
+ notIn?: $Enums.BountyStatus[] | Prisma.ListEnumBountyStatusFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumBountyStatusWithAggregatesFilter<$PrismaModel> | $Enums.BountyStatus
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedEnumBountyStatusFilter<$PrismaModel>
+ _max?: Prisma.NestedEnumBountyStatusFilter<$PrismaModel>
+}
+
+export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
+ in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
+ notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
+ lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null
+ _count?: Prisma.NestedIntNullableFilter<$PrismaModel>
+ _min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
+ _max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
+}
+
+export type EnumVolunteerAttendanceStatusFilter<$PrismaModel = never> = {
+ equals?: $Enums.VolunteerAttendanceStatus | Prisma.EnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ in?: $Enums.VolunteerAttendanceStatus[] | Prisma.ListEnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ notIn?: $Enums.VolunteerAttendanceStatus[] | Prisma.ListEnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumVolunteerAttendanceStatusFilter<$PrismaModel> | $Enums.VolunteerAttendanceStatus
+}
+
+export type EnumVolunteerAttendanceStatusWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: $Enums.VolunteerAttendanceStatus | Prisma.EnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ in?: $Enums.VolunteerAttendanceStatus[] | Prisma.ListEnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ notIn?: $Enums.VolunteerAttendanceStatus[] | Prisma.ListEnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumVolunteerAttendanceStatusWithAggregatesFilter<$PrismaModel> | $Enums.VolunteerAttendanceStatus
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedEnumVolunteerAttendanceStatusFilter<$PrismaModel>
+ _max?: Prisma.NestedEnumVolunteerAttendanceStatusFilter<$PrismaModel>
+}
+
+export type EnumRequirementLevelFilter<$PrismaModel = never> = {
+ equals?: $Enums.RequirementLevel | Prisma.EnumRequirementLevelFieldRefInput<$PrismaModel>
+ in?: $Enums.RequirementLevel[] | Prisma.ListEnumRequirementLevelFieldRefInput<$PrismaModel>
+ notIn?: $Enums.RequirementLevel[] | Prisma.ListEnumRequirementLevelFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumRequirementLevelFilter<$PrismaModel> | $Enums.RequirementLevel
+}
+
+export type EnumRequirementLevelWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: $Enums.RequirementLevel | Prisma.EnumRequirementLevelFieldRefInput<$PrismaModel>
+ in?: $Enums.RequirementLevel[] | Prisma.ListEnumRequirementLevelFieldRefInput<$PrismaModel>
+ notIn?: $Enums.RequirementLevel[] | Prisma.ListEnumRequirementLevelFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumRequirementLevelWithAggregatesFilter<$PrismaModel> | $Enums.RequirementLevel
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedEnumRequirementLevelFilter<$PrismaModel>
+ _max?: Prisma.NestedEnumRequirementLevelFilter<$PrismaModel>
+}
+
+export type NestedStringFilter<$PrismaModel = never> = {
+ equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
+ notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
+ lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedStringFilter<$PrismaModel> | string
+}
+
+export type NestedDateTimeFilter<$PrismaModel = never> = {
+ equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
+ notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
+ lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
+}
+
+export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
+ notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
+ lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedStringFilter<$PrismaModel>
+ _max?: Prisma.NestedStringFilter<$PrismaModel>
+}
+
+export type NestedIntFilter<$PrismaModel = never> = {
+ equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
+ notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
+ lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedIntFilter<$PrismaModel> | number
+}
+
+export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
+ notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
+ lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedDateTimeFilter<$PrismaModel>
+ _max?: Prisma.NestedDateTimeFilter<$PrismaModel>
+}
+
+export type NestedStringNullableFilter<$PrismaModel = never> = {
+ equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
+ in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
+ notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
+ lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
+}
+
+export type NestedDecimalNullableFilter<$PrismaModel = never> = {
+ equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null
+ in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
+ notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
+ lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDecimalNullableFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
+}
+
+export type NestedDecimalFilter<$PrismaModel = never> = {
+ equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel>
+ notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel>
+ lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDecimalFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string
+}
+
+export type NestedEnumBountyStatusFilter<$PrismaModel = never> = {
+ equals?: $Enums.BountyStatus | Prisma.EnumBountyStatusFieldRefInput<$PrismaModel>
+ in?: $Enums.BountyStatus[] | Prisma.ListEnumBountyStatusFieldRefInput<$PrismaModel>
+ notIn?: $Enums.BountyStatus[] | Prisma.ListEnumBountyStatusFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumBountyStatusFilter<$PrismaModel> | $Enums.BountyStatus
+}
+
+export type NestedDateTimeNullableFilter<$PrismaModel = never> = {
+ equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
+ in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
+ notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
+ lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null
+}
+
+export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
+ in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
+ notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
+ lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
+ _count?: Prisma.NestedIntNullableFilter<$PrismaModel>
+ _min?: Prisma.NestedStringNullableFilter<$PrismaModel>
+ _max?: Prisma.NestedStringNullableFilter<$PrismaModel>
+}
+
+export type NestedIntNullableFilter<$PrismaModel = never> = {
+ equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
+ in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
+ notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
+ lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null
+}
+
+export type NestedDecimalNullableWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null
+ in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
+ notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
+ lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDecimalNullableWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
+ _count?: Prisma.NestedIntNullableFilter<$PrismaModel>
+ _avg?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
+ _sum?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
+ _min?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
+ _max?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
+}
+
+export type NestedIntWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
+ notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
+ lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _avg?: Prisma.NestedFloatFilter<$PrismaModel>
+ _sum?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedIntFilter<$PrismaModel>
+ _max?: Prisma.NestedIntFilter<$PrismaModel>
+}
+
+export type NestedFloatFilter<$PrismaModel = never> = {
+ equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
+ in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
+ notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
+ lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
+ lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
+ gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
+ gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedFloatFilter<$PrismaModel> | number
+}
+
+export type NestedDecimalWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel>
+ notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel>
+ lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDecimalWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _avg?: Prisma.NestedDecimalFilter<$PrismaModel>
+ _sum?: Prisma.NestedDecimalFilter<$PrismaModel>
+ _min?: Prisma.NestedDecimalFilter<$PrismaModel>
+ _max?: Prisma.NestedDecimalFilter<$PrismaModel>
+}
+
+export type NestedEnumBountyStatusWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: $Enums.BountyStatus | Prisma.EnumBountyStatusFieldRefInput<$PrismaModel>
+ in?: $Enums.BountyStatus[] | Prisma.ListEnumBountyStatusFieldRefInput<$PrismaModel>
+ notIn?: $Enums.BountyStatus[] | Prisma.ListEnumBountyStatusFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumBountyStatusWithAggregatesFilter<$PrismaModel> | $Enums.BountyStatus
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedEnumBountyStatusFilter<$PrismaModel>
+ _max?: Prisma.NestedEnumBountyStatusFilter<$PrismaModel>
+}
+
+export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
+ in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
+ notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
+ lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null
+ _count?: Prisma.NestedIntNullableFilter<$PrismaModel>
+ _min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
+ _max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
+}
+
+export type NestedEnumVolunteerAttendanceStatusFilter<$PrismaModel = never> = {
+ equals?: $Enums.VolunteerAttendanceStatus | Prisma.EnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ in?: $Enums.VolunteerAttendanceStatus[] | Prisma.ListEnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ notIn?: $Enums.VolunteerAttendanceStatus[] | Prisma.ListEnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumVolunteerAttendanceStatusFilter<$PrismaModel> | $Enums.VolunteerAttendanceStatus
+}
+
+export type NestedEnumVolunteerAttendanceStatusWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: $Enums.VolunteerAttendanceStatus | Prisma.EnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ in?: $Enums.VolunteerAttendanceStatus[] | Prisma.ListEnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ notIn?: $Enums.VolunteerAttendanceStatus[] | Prisma.ListEnumVolunteerAttendanceStatusFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumVolunteerAttendanceStatusWithAggregatesFilter<$PrismaModel> | $Enums.VolunteerAttendanceStatus
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedEnumVolunteerAttendanceStatusFilter<$PrismaModel>
+ _max?: Prisma.NestedEnumVolunteerAttendanceStatusFilter<$PrismaModel>
+}
+
+export type NestedEnumRequirementLevelFilter<$PrismaModel = never> = {
+ equals?: $Enums.RequirementLevel | Prisma.EnumRequirementLevelFieldRefInput<$PrismaModel>
+ in?: $Enums.RequirementLevel[] | Prisma.ListEnumRequirementLevelFieldRefInput<$PrismaModel>
+ notIn?: $Enums.RequirementLevel[] | Prisma.ListEnumRequirementLevelFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumRequirementLevelFilter<$PrismaModel> | $Enums.RequirementLevel
+}
+
+export type NestedEnumRequirementLevelWithAggregatesFilter<$PrismaModel = never> = {
+ equals?: $Enums.RequirementLevel | Prisma.EnumRequirementLevelFieldRefInput<$PrismaModel>
+ in?: $Enums.RequirementLevel[] | Prisma.ListEnumRequirementLevelFieldRefInput<$PrismaModel>
+ notIn?: $Enums.RequirementLevel[] | Prisma.ListEnumRequirementLevelFieldRefInput<$PrismaModel>
+ not?: Prisma.NestedEnumRequirementLevelWithAggregatesFilter<$PrismaModel> | $Enums.RequirementLevel
+ _count?: Prisma.NestedIntFilter<$PrismaModel>
+ _min?: Prisma.NestedEnumRequirementLevelFilter<$PrismaModel>
+ _max?: Prisma.NestedEnumRequirementLevelFilter<$PrismaModel>
+}
+
+
diff --git a/generated/prisma/enums.ts b/generated/prisma/enums.ts
new file mode 100644
index 0000000..7cf1da5
--- /dev/null
+++ b/generated/prisma/enums.ts
@@ -0,0 +1,36 @@
+
+/* !!! This is code generated by Prisma. Do not edit directly. !!! */
+/* eslint-disable */
+// biome-ignore-all lint: generated file
+// @ts-nocheck
+/*
+* This file exports all enum related types from the schema.
+*
+* 🟢 You can import this file directly.
+*/
+
+export const BountyStatus = {
+ OPEN: 'OPEN',
+ FULL: 'FULL',
+ FINISHED: 'FINISHED',
+ CANCELLED: 'CANCELLED',
+ EXPIRED: 'EXPIRED'
+} as const
+
+export type BountyStatus = (typeof BountyStatus)[keyof typeof BountyStatus]
+
+
+export const RequirementLevel = {
+ REQUIRED: 'REQUIRED',
+ RECOMMENDED: 'RECOMMENDED'
+} as const
+
+export type RequirementLevel = (typeof RequirementLevel)[keyof typeof RequirementLevel]
+
+
+export const VolunteerAttendanceStatus = {
+ JOINED: 'JOINED',
+ WITHDRAWN: 'WITHDRAWN'
+} as const
+
+export type VolunteerAttendanceStatus = (typeof VolunteerAttendanceStatus)[keyof typeof VolunteerAttendanceStatus]
diff --git a/generated/prisma/internal/class.ts b/generated/prisma/internal/class.ts
new file mode 100644
index 0000000..9e81662
--- /dev/null
+++ b/generated/prisma/internal/class.ts
@@ -0,0 +1,244 @@
+
+/* !!! This is code generated by Prisma. Do not edit directly. !!! */
+/* eslint-disable */
+// biome-ignore-all lint: generated file
+// @ts-nocheck
+/*
+ * WARNING: This is an internal file that is subject to change!
+ *
+ * 🛑 Under no circumstances should you import this file directly! 🛑
+ *
+ * Please import the `PrismaClient` class from the `client.ts` file instead.
+ */
+
+import * as runtime from "@prisma/client/runtime/client"
+import type * as Prisma from "./prismaNamespace"
+
+
+const config: runtime.GetPrismaClientConfig = {
+ "previewFeatures": [],
+ "clientVersion": "7.10.0",
+ "engineVersion": "0edf323efd1d98336f3f0a68684b56f689b900d3",
+ "activeProvider": "postgresql",
+ "inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel User {\n id String @id @default(cuid())\n email String @unique\n displayName String\n passwordHash String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n postedBounties Bounty[] @relation(\"BountyPoster\")\n volunteerAttendances BountyVolunteer[]\n}\n\nenum BountyStatus {\n OPEN\n FULL\n FINISHED\n CANCELLED\n EXPIRED\n}\n\nenum RequirementLevel {\n REQUIRED\n RECOMMENDED\n}\n\nenum VolunteerAttendanceStatus {\n JOINED\n WITHDRAWN\n}\n\nmodel Bounty {\n id String @id @default(cuid())\n title String\n description String\n locationLabel String\n imageUrl String?\n latitude Decimal? @db.Decimal(9, 6)\n longitude Decimal? @db.Decimal(9, 6)\n scheduledAt DateTime\n deadline DateTime\n maxVolunteers Int\n payPerVolunteer Decimal @db.Decimal(10, 2)\n status BountyStatus @default(OPEN)\n posterId String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n finishedAt DateTime?\n verifiedAt DateTime?\n cancellationReason String?\n poster User @relation(\"BountyPoster\", fields: [posterId], references: [id], onDelete: Restrict)\n volunteerAttendances BountyVolunteer[]\n skillRequirements BountySkillRequirement[]\n equipmentRequirements BountyEquipmentRequirement[]\n\n @@index([posterId])\n @@index([status, deadline])\n @@index([scheduledAt])\n}\n\nmodel BountyVolunteer {\n bountyId String\n volunteerId String\n status VolunteerAttendanceStatus @default(JOINED)\n joinedAt DateTime @default(now())\n withdrawnAt DateTime?\n bounty Bounty @relation(fields: [bountyId], references: [id], onDelete: Cascade)\n volunteer User @relation(fields: [volunteerId], references: [id], onDelete: Cascade)\n\n @@id([bountyId, volunteerId])\n @@index([volunteerId, status])\n @@index([bountyId, status])\n}\n\nmodel BountySkillRequirement {\n id String @id @default(cuid())\n bountyId String\n name String\n level RequirementLevel\n bounty Bounty @relation(fields: [bountyId], references: [id], onDelete: Cascade)\n\n @@unique([bountyId, name])\n}\n\nmodel BountyEquipmentRequirement {\n id String @id @default(cuid())\n bountyId String\n name String\n level RequirementLevel\n bounty Bounty @relation(fields: [bountyId], references: [id], onDelete: Cascade)\n\n @@unique([bountyId, name])\n}\n",
+ "runtimeDataModel": {
+ "models": {},
+ "enums": {},
+ "types": {}
+ },
+ "parameterizationSchema": {
+ "strings": [],
+ "graph": ""
+ }
+}
+
+config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"displayName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"passwordHash\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"postedBounties\",\"kind\":\"object\",\"type\":\"Bounty\",\"relationName\":\"BountyPoster\"},{\"name\":\"volunteerAttendances\",\"kind\":\"object\",\"type\":\"BountyVolunteer\",\"relationName\":\"BountyVolunteerToUser\"}],\"dbName\":null,\"schema\":null},\"Bounty\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"title\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"description\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"locationLabel\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"imageUrl\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"latitude\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"longitude\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"scheduledAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deadline\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"maxVolunteers\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"payPerVolunteer\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"BountyStatus\"},{\"name\":\"posterId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"finishedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"verifiedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"cancellationReason\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"poster\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"BountyPoster\"},{\"name\":\"volunteerAttendances\",\"kind\":\"object\",\"type\":\"BountyVolunteer\",\"relationName\":\"BountyToBountyVolunteer\"},{\"name\":\"skillRequirements\",\"kind\":\"object\",\"type\":\"BountySkillRequirement\",\"relationName\":\"BountyToBountySkillRequirement\"},{\"name\":\"equipmentRequirements\",\"kind\":\"object\",\"type\":\"BountyEquipmentRequirement\",\"relationName\":\"BountyToBountyEquipmentRequirement\"}],\"dbName\":null,\"schema\":null},\"BountyVolunteer\":{\"fields\":[{\"name\":\"bountyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"volunteerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"VolunteerAttendanceStatus\"},{\"name\":\"joinedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"withdrawnAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"bounty\",\"kind\":\"object\",\"type\":\"Bounty\",\"relationName\":\"BountyToBountyVolunteer\"},{\"name\":\"volunteer\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"BountyVolunteerToUser\"}],\"dbName\":null,\"schema\":null},\"BountySkillRequirement\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bountyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"level\",\"kind\":\"enum\",\"type\":\"RequirementLevel\"},{\"name\":\"bounty\",\"kind\":\"object\",\"type\":\"Bounty\",\"relationName\":\"BountyToBountySkillRequirement\"}],\"dbName\":null,\"schema\":null},\"BountyEquipmentRequirement\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bountyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"level\",\"kind\":\"enum\",\"type\":\"RequirementLevel\"},{\"name\":\"bounty\",\"kind\":\"object\",\"type\":\"Bounty\",\"relationName\":\"BountyToBountyEquipmentRequirement\"}],\"dbName\":null,\"schema\":null}},\"enums\":{},\"types\":{}}")
+config.parameterizationSchema = {
+ strings: JSON.parse("[\"where\",\"orderBy\",\"cursor\",\"poster\",\"bounty\",\"volunteer\",\"volunteerAttendances\",\"skillRequirements\",\"equipmentRequirements\",\"_count\",\"postedBounties\",\"User.findUnique\",\"User.findUniqueOrThrow\",\"User.findFirst\",\"User.findFirstOrThrow\",\"User.findMany\",\"data\",\"User.createOne\",\"User.createMany\",\"User.createManyAndReturn\",\"User.updateOne\",\"User.updateMany\",\"User.updateManyAndReturn\",\"create\",\"update\",\"User.upsertOne\",\"User.deleteOne\",\"User.deleteMany\",\"having\",\"_min\",\"_max\",\"User.groupBy\",\"User.aggregate\",\"Bounty.findUnique\",\"Bounty.findUniqueOrThrow\",\"Bounty.findFirst\",\"Bounty.findFirstOrThrow\",\"Bounty.findMany\",\"Bounty.createOne\",\"Bounty.createMany\",\"Bounty.createManyAndReturn\",\"Bounty.updateOne\",\"Bounty.updateMany\",\"Bounty.updateManyAndReturn\",\"Bounty.upsertOne\",\"Bounty.deleteOne\",\"Bounty.deleteMany\",\"_avg\",\"_sum\",\"Bounty.groupBy\",\"Bounty.aggregate\",\"BountyVolunteer.findUnique\",\"BountyVolunteer.findUniqueOrThrow\",\"BountyVolunteer.findFirst\",\"BountyVolunteer.findFirstOrThrow\",\"BountyVolunteer.findMany\",\"BountyVolunteer.createOne\",\"BountyVolunteer.createMany\",\"BountyVolunteer.createManyAndReturn\",\"BountyVolunteer.updateOne\",\"BountyVolunteer.updateMany\",\"BountyVolunteer.updateManyAndReturn\",\"BountyVolunteer.upsertOne\",\"BountyVolunteer.deleteOne\",\"BountyVolunteer.deleteMany\",\"BountyVolunteer.groupBy\",\"BountyVolunteer.aggregate\",\"BountySkillRequirement.findUnique\",\"BountySkillRequirement.findUniqueOrThrow\",\"BountySkillRequirement.findFirst\",\"BountySkillRequirement.findFirstOrThrow\",\"BountySkillRequirement.findMany\",\"BountySkillRequirement.createOne\",\"BountySkillRequirement.createMany\",\"BountySkillRequirement.createManyAndReturn\",\"BountySkillRequirement.updateOne\",\"BountySkillRequirement.updateMany\",\"BountySkillRequirement.updateManyAndReturn\",\"BountySkillRequirement.upsertOne\",\"BountySkillRequirement.deleteOne\",\"BountySkillRequirement.deleteMany\",\"BountySkillRequirement.groupBy\",\"BountySkillRequirement.aggregate\",\"BountyEquipmentRequirement.findUnique\",\"BountyEquipmentRequirement.findUniqueOrThrow\",\"BountyEquipmentRequirement.findFirst\",\"BountyEquipmentRequirement.findFirstOrThrow\",\"BountyEquipmentRequirement.findMany\",\"BountyEquipmentRequirement.createOne\",\"BountyEquipmentRequirement.createMany\",\"BountyEquipmentRequirement.createManyAndReturn\",\"BountyEquipmentRequirement.updateOne\",\"BountyEquipmentRequirement.updateMany\",\"BountyEquipmentRequirement.updateManyAndReturn\",\"BountyEquipmentRequirement.upsertOne\",\"BountyEquipmentRequirement.deleteOne\",\"BountyEquipmentRequirement.deleteMany\",\"BountyEquipmentRequirement.groupBy\",\"BountyEquipmentRequirement.aggregate\",\"AND\",\"OR\",\"NOT\",\"id\",\"bountyId\",\"name\",\"RequirementLevel\",\"level\",\"equals\",\"in\",\"notIn\",\"not\",\"lt\",\"lte\",\"gt\",\"gte\",\"contains\",\"startsWith\",\"endsWith\",\"volunteerId\",\"VolunteerAttendanceStatus\",\"status\",\"joinedAt\",\"withdrawnAt\",\"title\",\"description\",\"locationLabel\",\"imageUrl\",\"latitude\",\"longitude\",\"scheduledAt\",\"deadline\",\"maxVolunteers\",\"payPerVolunteer\",\"BountyStatus\",\"posterId\",\"createdAt\",\"updatedAt\",\"finishedAt\",\"verifiedAt\",\"cancellationReason\",\"email\",\"displayName\",\"passwordHash\",\"every\",\"some\",\"none\",\"bountyId_name\",\"bountyId_volunteerId\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"),
+ graph: "0QItUAsGAACxAQAgCgAAsAEAIGMAAK0BADBkAAAaABBlAACtAQAwZgEAAAABhwFAAK8BACGIAUAArwEAIYwBAQAAAAGNAQEArgEAIY4BAQCuAQAhAQAAAAEAIBkDAAC8AQAgBgAAsQEAIAcAAMMBACAIAADEAQAgYwAAvQEAMGQAAAMAEGUAAL0BADBmAQCuAQAheAAAwgGGASJ7AQCuAQAhfAEArgEAIX0BAK4BACF-AQC-AQAhfxAAvwEAIYABEAC_AQAhgQFAAK8BACGCAUAArwEAIYMBAgDAAQAhhAEQAMEBACGGAQEArgEAIYcBQACvAQAhiAFAAK8BACGJAUAAuwEAIYoBQAC7AQAhiwEBAL4BACEKAwAAsQIAIAYAAK8CACAHAACyAgAgCAAAswIAIH4AANEBACB_AADRAQAggAEAANEBACCJAQAA0QEAIIoBAADRAQAgiwEAANEBACAZAwAAvAEAIAYAALEBACAHAADDAQAgCAAAxAEAIGMAAL0BADBkAAADABBlAAC9AQAwZgEAAAABeAAAwgGGASJ7AQCuAQAhfAEArgEAIX0BAK4BACF-AQC-AQAhfxAAvwEAIYABEAC_AQAhgQFAAK8BACGCAUAArwEAIYMBAgDAAQAhhAEQAMEBACGGAQEArgEAIYcBQACvAQAhiAFAAK8BACGJAUAAuwEAIYoBQAC7AQAhiwEBAL4BACEDAAAAAwAgAQAABAAwAgAABQAgCgQAALUBACAFAAC8AQAgYwAAuQEAMGQAAAcAEGUAALkBADBnAQCuAQAhdgEArgEAIXgAALoBeCJ5QACvAQAhekAAuwEAIQMEAACwAgAgBQAAsQIAIHoAANEBACALBAAAtQEAIAUAALwBACBjAAC5AQAwZAAABwAQZQAAuQEAMGcBAK4BACF2AQCuAQAheAAAugF4InlAAK8BACF6QAC7AQAhkwEAALgBACADAAAABwAgAQAACAAwAgAACQAgCAQAALUBACBjAAC3AQAwZAAACwAQZQAAtwEAMGYBAK4BACFnAQCuAQAhaAEArgEAIWoAALQBaiIBBAAAsAIAIAkEAAC1AQAgYwAAtwEAMGQAAAsAEGUAALcBADBmAQAAAAFnAQCuAQAhaAEArgEAIWoAALQBaiKSAQAAtgEAIAMAAAALACABAAAMADACAAANACAIBAAAtQEAIGMAALMBADBkAAAPABBlAACzAQAwZgEArgEAIWcBAK4BACFoAQCuAQAhagAAtAFqIgEEAACwAgAgCQQAALUBACBjAACzAQAwZAAADwAQZQAAswEAMGYBAAAAAWcBAK4BACFoAQCuAQAhagAAtAFqIpIBAACyAQAgAwAAAA8AIAEAABAAMAIAABEAIAEAAAAHACABAAAACwAgAQAAAA8AIAMAAAAHACABAAAIADACAAAJACABAAAAAwAgAQAAAAcAIAEAAAABACALBgAAsQEAIAoAALABACBjAACtAQAwZAAAGgAQZQAArQEAMGYBAK4BACGHAUAArwEAIYgBQACvAQAhjAEBAK4BACGNAQEArgEAIY4BAQCuAQAhAgYAAK8CACAKAACuAgAgAwAAABoAIAEAABsAMAIAAAEAIAMAAAAaACABAAAbADACAAABACADAAAAGgAgAQAAGwAwAgAAAQAgCAYAAK0CACAKAACsAgAgZgEAAAABhwFAAAAAAYgBQAAAAAGMAQEAAAABjQEBAAAAAY4BAQAAAAEBEAAAHwAgBmYBAAAAAYcBQAAAAAGIAUAAAAABjAEBAAAAAY0BAQAAAAGOAQEAAAABARAAACEAMAEQAAAhADAIBgAAlgIAIAoAAJUCACBmAQDIAQAhhwFAANYBACGIAUAA1gEAIYwBAQDIAQAhjQEBAMgBACGOAQEAyAEAIQIAAAABACAQAAAkACAGZgEAyAEAIYcBQADWAQAhiAFAANYBACGMAQEAyAEAIY0BAQDIAQAhjgEBAMgBACECAAAAGgAgEAAAJgAgAgAAABoAIBAAACYAIAMAAAABACAXAAAfACAYAAAkACABAAAAAQAgAQAAABoAIAMJAACSAgAgHQAAlAIAIB4AAJMCACAJYwAArAEAMGQAAC0AEGUAAKwBADBmAQCJAQAhhwFAAJMBACGIAUAAkwEAIYwBAQCJAQAhjQEBAIkBACGOAQEAiQEAIQMAAAAaACABAAAsADAcAAAtACADAAAAGgAgAQAAGwAwAgAAAQAgAQAAAAUAIAEAAAAFACADAAAAAwAgAQAABAAwAgAABQAgAwAAAAMAIAEAAAQAMAIAAAUAIAMAAAADACABAAAEADACAAAFACAWAwAAjgIAIAYAAI8CACAHAACQAgAgCAAAkQIAIGYBAAAAAXgAAACGAQJ7AQAAAAF8AQAAAAF9AQAAAAF-AQAAAAF_EAAAAAGAARAAAAABgQFAAAAAAYIBQAAAAAGDAQIAAAABhAEQAAAAAYYBAQAAAAGHAUAAAAABiAFAAAAAAYkBQAAAAAGKAUAAAAABiwEBAAAAAQEQAAA1ACASZgEAAAABeAAAAIYBAnsBAAAAAXwBAAAAAX0BAAAAAX4BAAAAAX8QAAAAAYABEAAAAAGBAUAAAAABggFAAAAAAYMBAgAAAAGEARAAAAABhgEBAAAAAYcBQAAAAAGIAUAAAAABiQFAAAAAAYoBQAAAAAGLAQEAAAABARAAADcAMAEQAAA3ADAWAwAA5gEAIAYAAOcBACAHAADoAQAgCAAA6QEAIGYBAMgBACF4AADlAYYBInsBAMgBACF8AQDIAQAhfQEAyAEAIX4BAOEBACF_EADiAQAhgAEQAOIBACGBAUAA1gEAIYIBQADWAQAhgwECAOMBACGEARAA5AEAIYYBAQDIAQAhhwFAANYBACGIAUAA1gEAIYkBQADXAQAhigFAANcBACGLAQEA4QEAIQIAAAAFACAQAAA6ACASZgEAyAEAIXgAAOUBhgEiewEAyAEAIXwBAMgBACF9AQDIAQAhfgEA4QEAIX8QAOIBACGAARAA4gEAIYEBQADWAQAhggFAANYBACGDAQIA4wEAIYQBEADkAQAhhgEBAMgBACGHAUAA1gEAIYgBQADWAQAhiQFAANcBACGKAUAA1wEAIYsBAQDhAQAhAgAAAAMAIBAAADwAIAIAAAADACAQAAA8ACADAAAABQAgFwAANQAgGAAAOgAgAQAAAAUAIAEAAAADACALCQAA3AEAIB0AAN8BACAeAADeAQAgLwAA3QEAIDAAAOABACB-AADRAQAgfwAA0QEAIIABAADRAQAgiQEAANEBACCKAQAA0QEAIIsBAADRAQAgFWMAAJwBADBkAABDABBlAACcAQAwZgEAiQEAIXgAAKEBhgEiewEAiQEAIXwBAIkBACF9AQCJAQAhfgEAnQEAIX8QAJ4BACGAARAAngEAIYEBQACTAQAhggFAAJMBACGDAQIAnwEAIYQBEACgAQAhhgEBAIkBACGHAUAAkwEAIYgBQACTAQAhiQFAAJQBACGKAUAAlAEAIYsBAQCdAQAhAwAAAAMAIAEAAEIAMBwAAEMAIAMAAAADACABAAAEADACAAAFACABAAAACQAgAQAAAAkAIAMAAAAHACABAAAIADACAAAJACADAAAABwAgAQAACAAwAgAACQAgAwAAAAcAIAEAAAgAMAIAAAkAIAcEAADaAQAgBQAA2wEAIGcBAAAAAXYBAAAAAXgAAAB4AnlAAAAAAXpAAAAAAQEQAABLACAFZwEAAAABdgEAAAABeAAAAHgCeUAAAAABekAAAAABARAAAE0AMAEQAABNADAHBAAA2AEAIAUAANkBACBnAQDIAQAhdgEAyAEAIXgAANUBeCJ5QADWAQAhekAA1wEAIQIAAAAJACAQAABQACAFZwEAyAEAIXYBAMgBACF4AADVAXgieUAA1gEAIXpAANcBACECAAAABwAgEAAAUgAgAgAAAAcAIBAAAFIAIAMAAAAJACAXAABLACAYAABQACABAAAACQAgAQAAAAcAIAQJAADSAQAgHQAA1AEAIB4AANMBACB6AADRAQAgCGMAAJEBADBkAABZABBlAACRAQAwZwEAiQEAIXYBAIkBACF4AACSAXgieUAAkwEAIXpAAJQBACEDAAAABwAgAQAAWAAwHAAAWQAgAwAAAAcAIAEAAAgAMAIAAAkAIAEAAAANACABAAAADQAgAwAAAAsAIAEAAAwAMAIAAA0AIAMAAAALACABAAAMADACAAANACADAAAACwAgAQAADAAwAgAADQAgBQQAANABACBmAQAAAAFnAQAAAAFoAQAAAAFqAAAAagIBEAAAYQAgBGYBAAAAAWcBAAAAAWgBAAAAAWoAAABqAgEQAABjADABEAAAYwAwBQQAAM8BACBmAQDIAQAhZwEAyAEAIWgBAMgBACFqAADJAWoiAgAAAA0AIBAAAGYAIARmAQDIAQAhZwEAyAEAIWgBAMgBACFqAADJAWoiAgAAAAsAIBAAAGgAIAIAAAALACAQAABoACADAAAADQAgFwAAYQAgGAAAZgAgAQAAAA0AIAEAAAALACADCQAAzAEAIB0AAM4BACAeAADNAQAgB2MAAJABADBkAABvABBlAACQAQAwZgEAiQEAIWcBAIkBACFoAQCJAQAhagAAigFqIgMAAAALACABAABuADAcAABvACADAAAACwAgAQAADAAwAgAADQAgAQAAABEAIAEAAAARACADAAAADwAgAQAAEAAwAgAAEQAgAwAAAA8AIAEAABAAMAIAABEAIAMAAAAPACABAAAQADACAAARACAFBAAAywEAIGYBAAAAAWcBAAAAAWgBAAAAAWoAAABqAgEQAAB3ACAEZgEAAAABZwEAAAABaAEAAAABagAAAGoCARAAAHkAMAEQAAB5ADAFBAAAygEAIGYBAMgBACFnAQDIAQAhaAEAyAEAIWoAAMkBaiICAAAAEQAgEAAAfAAgBGYBAMgBACFnAQDIAQAhaAEAyAEAIWoAAMkBaiICAAAADwAgEAAAfgAgAgAAAA8AIBAAAH4AIAMAAAARACAXAAB3ACAYAAB8ACABAAAAEQAgAQAAAA8AIAMJAADFAQAgHQAAxwEAIB4AAMYBACAHYwAAiAEAMGQAAIUBABBlAACIAQAwZgEAiQEAIWcBAIkBACFoAQCJAQAhagAAigFqIgMAAAAPACABAACEAQAwHAAAhQEAIAMAAAAPACABAAAQADACAAARACAHYwAAiAEAMGQAAIUBABBlAACIAQAwZgEAiQEAIWcBAIkBACFoAQCJAQAhagAAigFqIg4JAACMAQAgHQAAjwEAIB4AAI8BACBrAQAAAAFsAQAAAARtAQAAAARuAQCOAQAhbwEAAAABcAEAAAABcQEAAAABcgEAAAABcwEAAAABdAEAAAABdQEAAAABBwkAAIwBACAdAACNAQAgHgAAjQEAIGsAAABqAmwAAABqCG0AAABqCG4AAIsBaiIHCQAAjAEAIB0AAI0BACAeAACNAQAgawAAAGoCbAAAAGoIbQAAAGoIbgAAiwFqIghrAgAAAAFsAgAAAARtAgAAAARuAgCMAQAhbwIAAAABcAIAAAABcQIAAAABcgIAAAABBGsAAABqAmwAAABqCG0AAABqCG4AAI0BaiIOCQAAjAEAIB0AAI8BACAeAACPAQAgawEAAAABbAEAAAAEbQEAAAAEbgEAjgEAIW8BAAAAAXABAAAAAXEBAAAAAXIBAAAAAXMBAAAAAXQBAAAAAXUBAAAAAQtrAQAAAAFsAQAAAARtAQAAAARuAQCPAQAhbwEAAAABcAEAAAABcQEAAAABcgEAAAABcwEAAAABdAEAAAABdQEAAAABB2MAAJABADBkAABvABBlAACQAQAwZgEAiQEAIWcBAIkBACFoAQCJAQAhagAAigFqIghjAACRAQAwZAAAWQAQZQAAkQEAMGcBAIkBACF2AQCJAQAheAAAkgF4InlAAJMBACF6QACUAQAhBwkAAIwBACAdAACbAQAgHgAAmwEAIGsAAAB4AmwAAAB4CG0AAAB4CG4AAJoBeCILCQAAjAEAIB0AAJkBACAeAACZAQAga0AAAAABbEAAAAAEbUAAAAAEbkAAmAEAIW9AAAAAAXBAAAAAAXFAAAAAAXJAAAAAAQsJAACWAQAgHQAAlwEAIB4AAJcBACBrQAAAAAFsQAAAAAVtQAAAAAVuQACVAQAhb0AAAAABcEAAAAABcUAAAAABckAAAAABCwkAAJYBACAdAACXAQAgHgAAlwEAIGtAAAAAAWxAAAAABW1AAAAABW5AAJUBACFvQAAAAAFwQAAAAAFxQAAAAAFyQAAAAAEIawIAAAABbAIAAAAFbQIAAAAFbgIAlgEAIW8CAAAAAXACAAAAAXECAAAAAXICAAAAAQhrQAAAAAFsQAAAAAVtQAAAAAVuQACXAQAhb0AAAAABcEAAAAABcUAAAAABckAAAAABCwkAAIwBACAdAACZAQAgHgAAmQEAIGtAAAAAAWxAAAAABG1AAAAABG5AAJgBACFvQAAAAAFwQAAAAAFxQAAAAAFyQAAAAAEIa0AAAAABbEAAAAAEbUAAAAAEbkAAmQEAIW9AAAAAAXBAAAAAAXFAAAAAAXJAAAAAAQcJAACMAQAgHQAAmwEAIB4AAJsBACBrAAAAeAJsAAAAeAhtAAAAeAhuAACaAXgiBGsAAAB4AmwAAAB4CG0AAAB4CG4AAJsBeCIVYwAAnAEAMGQAAEMAEGUAAJwBADBmAQCJAQAheAAAoQGGASJ7AQCJAQAhfAEAiQEAIX0BAIkBACF-AQCdAQAhfxAAngEAIYABEACeAQAhgQFAAJMBACGCAUAAkwEAIYMBAgCfAQAhhAEQAKABACGGAQEAiQEAIYcBQACTAQAhiAFAAJMBACGJAUAAlAEAIYoBQACUAQAhiwEBAJ0BACEOCQAAlgEAIB0AAKsBACAeAACrAQAgawEAAAABbAEAAAAFbQEAAAAFbgEAqgEAIW8BAAAAAXABAAAAAXEBAAAAAXIBAAAAAXMBAAAAAXQBAAAAAXUBAAAAAQ0JAACWAQAgHQAAqQEAIB4AAKkBACAvAACpAQAgMAAAqQEAIGsQAAAAAWwQAAAABW0QAAAABW4QAKgBACFvEAAAAAFwEAAAAAFxEAAAAAFyEAAAAAENCQAAjAEAIB0AAIwBACAeAACMAQAgLwAApwEAIDAAAIwBACBrAgAAAAFsAgAAAARtAgAAAARuAgCmAQAhbwIAAAABcAIAAAABcQIAAAABcgIAAAABDQkAAIwBACAdAAClAQAgHgAApQEAIC8AAKUBACAwAAClAQAgaxAAAAABbBAAAAAEbRAAAAAEbhAApAEAIW8QAAAAAXAQAAAAAXEQAAAAAXIQAAAAAQcJAACMAQAgHQAAowEAIB4AAKMBACBrAAAAhgECbAAAAIYBCG0AAACGAQhuAACiAYYBIgcJAACMAQAgHQAAowEAIB4AAKMBACBrAAAAhgECbAAAAIYBCG0AAACGAQhuAACiAYYBIgRrAAAAhgECbAAAAIYBCG0AAACGAQhuAACjAYYBIg0JAACMAQAgHQAApQEAIB4AAKUBACAvAAClAQAgMAAApQEAIGsQAAAAAWwQAAAABG0QAAAABG4QAKQBACFvEAAAAAFwEAAAAAFxEAAAAAFyEAAAAAEIaxAAAAABbBAAAAAEbRAAAAAEbhAApQEAIW8QAAAAAXAQAAAAAXEQAAAAAXIQAAAAAQ0JAACMAQAgHQAAjAEAIB4AAIwBACAvAACnAQAgMAAAjAEAIGsCAAAAAWwCAAAABG0CAAAABG4CAKYBACFvAgAAAAFwAgAAAAFxAgAAAAFyAgAAAAEIawgAAAABbAgAAAAEbQgAAAAEbggApwEAIW8IAAAAAXAIAAAAAXEIAAAAAXIIAAAAAQ0JAACWAQAgHQAAqQEAIB4AAKkBACAvAACpAQAgMAAAqQEAIGsQAAAAAWwQAAAABW0QAAAABW4QAKgBACFvEAAAAAFwEAAAAAFxEAAAAAFyEAAAAAEIaxAAAAABbBAAAAAFbRAAAAAFbhAAqQEAIW8QAAAAAXAQAAAAAXEQAAAAAXIQAAAAAQ4JAACWAQAgHQAAqwEAIB4AAKsBACBrAQAAAAFsAQAAAAVtAQAAAAVuAQCqAQAhbwEAAAABcAEAAAABcQEAAAABcgEAAAABcwEAAAABdAEAAAABdQEAAAABC2sBAAAAAWwBAAAABW0BAAAABW4BAKsBACFvAQAAAAFwAQAAAAFxAQAAAAFyAQAAAAFzAQAAAAF0AQAAAAF1AQAAAAEJYwAArAEAMGQAAC0AEGUAAKwBADBmAQCJAQAhhwFAAJMBACGIAUAAkwEAIYwBAQCJAQAhjQEBAIkBACGOAQEAiQEAIQsGAACxAQAgCgAAsAEAIGMAAK0BADBkAAAaABBlAACtAQAwZgEArgEAIYcBQACvAQAhiAFAAK8BACGMAQEArgEAIY0BAQCuAQAhjgEBAK4BACELawEAAAABbAEAAAAEbQEAAAAEbgEAjwEAIW8BAAAAAXABAAAAAXEBAAAAAXIBAAAAAXMBAAAAAXQBAAAAAXUBAAAAAQhrQAAAAAFsQAAAAARtQAAAAARuQACZAQAhb0AAAAABcEAAAAABcUAAAAABckAAAAABA48BAAADACCQAQAAAwAgkQEAAAMAIAOPAQAABwAgkAEAAAcAIJEBAAAHACACZwEAAAABaAEAAAABCAQAALUBACBjAACzAQAwZAAADwAQZQAAswEAMGYBAK4BACFnAQCuAQAhaAEArgEAIWoAALQBaiIEawAAAGoCbAAAAGoIbQAAAGoIbgAAjQFqIhsDAAC8AQAgBgAAsQEAIAcAAMMBACAIAADEAQAgYwAAvQEAMGQAAAMAEGUAAL0BADBmAQCuAQAheAAAwgGGASJ7AQCuAQAhfAEArgEAIX0BAK4BACF-AQC-AQAhfxAAvwEAIYABEAC_AQAhgQFAAK8BACGCAUAArwEAIYMBAgDAAQAhhAEQAMEBACGGAQEArgEAIYcBQACvAQAhiAFAAK8BACGJAUAAuwEAIYoBQAC7AQAhiwEBAL4BACGUAQAAAwAglQEAAAMAIAJnAQAAAAFoAQAAAAEIBAAAtQEAIGMAALcBADBkAAALABBlAAC3AQAwZgEArgEAIWcBAK4BACFoAQCuAQAhagAAtAFqIgJnAQAAAAF2AQAAAAEKBAAAtQEAIAUAALwBACBjAAC5AQAwZAAABwAQZQAAuQEAMGcBAK4BACF2AQCuAQAheAAAugF4InlAAK8BACF6QAC7AQAhBGsAAAB4AmwAAAB4CG0AAAB4CG4AAJsBeCIIa0AAAAABbEAAAAAFbUAAAAAFbkAAlwEAIW9AAAAAAXBAAAAAAXFAAAAAAXJAAAAAAQ0GAACxAQAgCgAAsAEAIGMAAK0BADBkAAAaABBlAACtAQAwZgEArgEAIYcBQACvAQAhiAFAAK8BACGMAQEArgEAIY0BAQCuAQAhjgEBAK4BACGUAQAAGgAglQEAABoAIBkDAAC8AQAgBgAAsQEAIAcAAMMBACAIAADEAQAgYwAAvQEAMGQAAAMAEGUAAL0BADBmAQCuAQAheAAAwgGGASJ7AQCuAQAhfAEArgEAIX0BAK4BACF-AQC-AQAhfxAAvwEAIYABEAC_AQAhgQFAAK8BACGCAUAArwEAIYMBAgDAAQAhhAEQAMEBACGGAQEArgEAIYcBQACvAQAhiAFAAK8BACGJAUAAuwEAIYoBQAC7AQAhiwEBAL4BACELawEAAAABbAEAAAAFbQEAAAAFbgEAqwEAIW8BAAAAAXABAAAAAXEBAAAAAXIBAAAAAXMBAAAAAXQBAAAAAXUBAAAAAQhrEAAAAAFsEAAAAAVtEAAAAAVuEACpAQAhbxAAAAABcBAAAAABcRAAAAABchAAAAABCGsCAAAAAWwCAAAABG0CAAAABG4CAIwBACFvAgAAAAFwAgAAAAFxAgAAAAFyAgAAAAEIaxAAAAABbBAAAAAEbRAAAAAEbhAApQEAIW8QAAAAAXAQAAAAAXEQAAAAAXIQAAAAAQRrAAAAhgECbAAAAIYBCG0AAACGAQhuAACjAYYBIgOPAQAACwAgkAEAAAsAIJEBAAALACADjwEAAA8AIJABAAAPACCRAQAADwAgAAAAAZkBAQAAAAEBmQEAAABqAgUXAADNAgAgGAAA0AIAIJYBAADOAgAglwEAAM8CACCcAQAABQAgAxcAAM0CACCWAQAAzgIAIJwBAAAFACAAAAAFFwAAyAIAIBgAAMsCACCWAQAAyQIAIJcBAADKAgAgnAEAAAUAIAMXAADIAgAglgEAAMkCACCcAQAABQAgAAAAAAGZAQAAAHgCAZkBQAAAAAEBmQFAAAAAAQUXAADAAgAgGAAAxgIAIJYBAADBAgAglwEAAMUCACCcAQAABQAgBRcAAL4CACAYAADDAgAglgEAAL8CACCXAQAAwgIAIJwBAAABACADFwAAwAIAIJYBAADBAgAgnAEAAAUAIAMXAAC-AgAglgEAAL8CACCcAQAAAQAgAAAAAAABmQEBAAAAAQWZARAAAAABnwEQAAAAAaABEAAAAAGhARAAAAABogEQAAAAAQWZAQIAAAABnwECAAAAAaABAgAAAAGhAQIAAAABogECAAAAAQWZARAAAAABnwEQAAAAAaABEAAAAAGhARAAAAABogEQAAAAAQGZAQAAAIYBAgUXAAC2AgAgGAAAvAIAIJYBAAC3AgAglwEAALsCACCcAQAAAQAgCxcAAIICADAYAACHAgAwlgEAAIMCADCXAQAAhAIAMJgBAACFAgAgmQEAAIYCADCaAQAAhgIAMJsBAACGAgAwnAEAAIYCADCdAQAAiAIAMJ4BAACJAgAwCxcAAPYBADAYAAD7AQAwlgEAAPcBADCXAQAA-AEAMJgBAAD5AQAgmQEAAPoBADCaAQAA-gEAMJsBAAD6AQAwnAEAAPoBADCdAQAA_AEAMJ4BAAD9AQAwCxcAAOoBADAYAADvAQAwlgEAAOsBADCXAQAA7AEAMJgBAADtAQAgmQEAAO4BADCaAQAA7gEAMJsBAADuAQAwnAEAAO4BADCdAQAA8AEAMJ4BAADxAQAwA2YBAAAAAWgBAAAAAWoAAABqAgIAAAARACAXAAD1AQAgAwAAABEAIBcAAPUBACAYAAD0AQAgARAAALoCADAJBAAAtQEAIGMAALMBADBkAAAPABBlAACzAQAwZgEAAAABZwEArgEAIWgBAK4BACFqAAC0AWoikgEAALIBACACAAAAEQAgEAAA9AEAIAIAAADyAQAgEAAA8wEAIAdjAADxAQAwZAAA8gEAEGUAAPEBADBmAQCuAQAhZwEArgEAIWgBAK4BACFqAAC0AWoiB2MAAPEBADBkAADyAQAQZQAA8QEAMGYBAK4BACFnAQCuAQAhaAEArgEAIWoAALQBaiIDZgEAyAEAIWgBAMgBACFqAADJAWoiA2YBAMgBACFoAQDIAQAhagAAyQFqIgNmAQAAAAFoAQAAAAFqAAAAagIDZgEAAAABaAEAAAABagAAAGoCAgAAAA0AIBcAAIECACADAAAADQAgFwAAgQIAIBgAAIACACABEAAAuQIAMAkEAAC1AQAgYwAAtwEAMGQAAAsAEGUAALcBADBmAQAAAAFnAQCuAQAhaAEArgEAIWoAALQBaiKSAQAAtgEAIAIAAAANACAQAACAAgAgAgAAAP4BACAQAAD_AQAgB2MAAP0BADBkAAD-AQAQZQAA_QEAMGYBAK4BACFnAQCuAQAhaAEArgEAIWoAALQBaiIHYwAA_QEAMGQAAP4BABBlAAD9AQAwZgEArgEAIWcBAK4BACFoAQCuAQAhagAAtAFqIgNmAQDIAQAhaAEAyAEAIWoAAMkBaiIDZgEAyAEAIWgBAMgBACFqAADJAWoiA2YBAAAAAWgBAAAAAWoAAABqAgUFAADbAQAgdgEAAAABeAAAAHgCeUAAAAABekAAAAABAgAAAAkAIBcAAI0CACADAAAACQAgFwAAjQIAIBgAAIwCACABEAAAuAIAMAsEAAC1AQAgBQAAvAEAIGMAALkBADBkAAAHABBlAAC5AQAwZwEArgEAIXYBAK4BACF4AAC6AXgieUAArwEAIXpAALsBACGTAQAAuAEAIAIAAAAJACAQAACMAgAgAgAAAIoCACAQAACLAgAgCGMAAIkCADBkAACKAgAQZQAAiQIAMGcBAK4BACF2AQCuAQAheAAAugF4InlAAK8BACF6QAC7AQAhCGMAAIkCADBkAACKAgAQZQAAiQIAMGcBAK4BACF2AQCuAQAheAAAugF4InlAAK8BACF6QAC7AQAhBHYBAMgBACF4AADVAXgieUAA1gEAIXpAANcBACEFBQAA2QEAIHYBAMgBACF4AADVAXgieUAA1gEAIXpAANcBACEFBQAA2wEAIHYBAAAAAXgAAAB4AnlAAAAAAXpAAAAAAQMXAAC2AgAglgEAALcCACCcAQAAAQAgBBcAAIICADCWAQAAgwIAMJgBAACFAgAgnAEAAIYCADAEFwAA9gEAMJYBAAD3AQAwmAEAAPkBACCcAQAA-gEAMAQXAADqAQAwlgEAAOsBADCYAQAA7QEAIJwBAADuAQAwAAAACxcAAKACADAYAAClAgAwlgEAAKECADCXAQAAogIAMJgBAACjAgAgmQEAAKQCADCaAQAApAIAMJsBAACkAgAwnAEAAKQCADCdAQAApgIAMJ4BAACnAgAwCxcAAJcCADAYAACbAgAwlgEAAJgCADCXAQAAmQIAMJgBAACaAgAgmQEAAIYCADCaAQAAhgIAMJsBAACGAgAwnAEAAIYCADCdAQAAnAIAMJ4BAACJAgAwBQQAANoBACBnAQAAAAF4AAAAeAJ5QAAAAAF6QAAAAAECAAAACQAgFwAAnwIAIAMAAAAJACAXAACfAgAgGAAAngIAIAEQAAC1AgAwAgAAAAkAIBAAAJ4CACACAAAAigIAIBAAAJ0CACAEZwEAyAEAIXgAANUBeCJ5QADWAQAhekAA1wEAIQUEAADYAQAgZwEAyAEAIXgAANUBeCJ5QADWAQAhekAA1wEAIQUEAADaAQAgZwEAAAABeAAAAHgCeUAAAAABekAAAAABFAYAAI8CACAHAACQAgAgCAAAkQIAIGYBAAAAAXgAAACGAQJ7AQAAAAF8AQAAAAF9AQAAAAF-AQAAAAF_EAAAAAGAARAAAAABgQFAAAAAAYIBQAAAAAGDAQIAAAABhAEQAAAAAYcBQAAAAAGIAUAAAAABiQFAAAAAAYoBQAAAAAGLAQEAAAABAgAAAAUAIBcAAKsCACADAAAABQAgFwAAqwIAIBgAAKoCACABEAAAtAIAMBkDAAC8AQAgBgAAsQEAIAcAAMMBACAIAADEAQAgYwAAvQEAMGQAAAMAEGUAAL0BADBmAQAAAAF4AADCAYYBInsBAK4BACF8AQCuAQAhfQEArgEAIX4BAL4BACF_EAC_AQAhgAEQAL8BACGBAUAArwEAIYIBQACvAQAhgwECAMABACGEARAAwQEAIYYBAQCuAQAhhwFAAK8BACGIAUAArwEAIYkBQAC7AQAhigFAALsBACGLAQEAvgEAIQIAAAAFACAQAACqAgAgAgAAAKgCACAQAACpAgAgFWMAAKcCADBkAACoAgAQZQAApwIAMGYBAK4BACF4AADCAYYBInsBAK4BACF8AQCuAQAhfQEArgEAIX4BAL4BACF_EAC_AQAhgAEQAL8BACGBAUAArwEAIYIBQACvAQAhgwECAMABACGEARAAwQEAIYYBAQCuAQAhhwFAAK8BACGIAUAArwEAIYkBQAC7AQAhigFAALsBACGLAQEAvgEAIRVjAACnAgAwZAAAqAIAEGUAAKcCADBmAQCuAQAheAAAwgGGASJ7AQCuAQAhfAEArgEAIX0BAK4BACF-AQC-AQAhfxAAvwEAIYABEAC_AQAhgQFAAK8BACGCAUAArwEAIYMBAgDAAQAhhAEQAMEBACGGAQEArgEAIYcBQACvAQAhiAFAAK8BACGJAUAAuwEAIYoBQAC7AQAhiwEBAL4BACERZgEAyAEAIXgAAOUBhgEiewEAyAEAIXwBAMgBACF9AQDIAQAhfgEA4QEAIX8QAOIBACGAARAA4gEAIYEBQADWAQAhggFAANYBACGDAQIA4wEAIYQBEADkAQAhhwFAANYBACGIAUAA1gEAIYkBQADXAQAhigFAANcBACGLAQEA4QEAIRQGAADnAQAgBwAA6AEAIAgAAOkBACBmAQDIAQAheAAA5QGGASJ7AQDIAQAhfAEAyAEAIX0BAMgBACF-AQDhAQAhfxAA4gEAIYABEADiAQAhgQFAANYBACGCAUAA1gEAIYMBAgDjAQAhhAEQAOQBACGHAUAA1gEAIYgBQADWAQAhiQFAANcBACGKAUAA1wEAIYsBAQDhAQAhFAYAAI8CACAHAACQAgAgCAAAkQIAIGYBAAAAAXgAAACGAQJ7AQAAAAF8AQAAAAF9AQAAAAF-AQAAAAF_EAAAAAGAARAAAAABgQFAAAAAAYIBQAAAAAGDAQIAAAABhAEQAAAAAYcBQAAAAAGIAUAAAAABiQFAAAAAAYoBQAAAAAGLAQEAAAABBBcAAKACADCWAQAAoQIAMJgBAACjAgAgnAEAAKQCADAEFwAAlwIAMJYBAACYAgAwmAEAAJoCACCcAQAAhgIAMAAACgMAALECACAGAACvAgAgBwAAsgIAIAgAALMCACB-AADRAQAgfwAA0QEAIIABAADRAQAgiQEAANEBACCKAQAA0QEAIIsBAADRAQAgAgYAAK8CACAKAACuAgAgAAARZgEAAAABeAAAAIYBAnsBAAAAAXwBAAAAAX0BAAAAAX4BAAAAAX8QAAAAAYABEAAAAAGBAUAAAAABggFAAAAAAYMBAgAAAAGEARAAAAABhwFAAAAAAYgBQAAAAAGJAUAAAAABigFAAAAAAYsBAQAAAAEEZwEAAAABeAAAAHgCeUAAAAABekAAAAABBwYAAK0CACBmAQAAAAGHAUAAAAABiAFAAAAAAYwBAQAAAAGNAQEAAAABjgEBAAAAAQIAAAABACAXAAC2AgAgBHYBAAAAAXgAAAB4AnlAAAAAAXpAAAAAAQNmAQAAAAFoAQAAAAFqAAAAagIDZgEAAAABaAEAAAABagAAAGoCAwAAABoAIBcAALYCACAYAAC9AgAgCQAAABoAIAYAAJYCACAQAAC9AgAgZgEAyAEAIYcBQADWAQAhiAFAANYBACGMAQEAyAEAIY0BAQDIAQAhjgEBAMgBACEHBgAAlgIAIGYBAMgBACGHAUAA1gEAIYgBQADWAQAhjAEBAMgBACGNAQEAyAEAIY4BAQDIAQAhBwoAAKwCACBmAQAAAAGHAUAAAAABiAFAAAAAAYwBAQAAAAGNAQEAAAABjgEBAAAAAQIAAAABACAXAAC-AgAgFQMAAI4CACAHAACQAgAgCAAAkQIAIGYBAAAAAXgAAACGAQJ7AQAAAAF8AQAAAAF9AQAAAAF-AQAAAAF_EAAAAAGAARAAAAABgQFAAAAAAYIBQAAAAAGDAQIAAAABhAEQAAAAAYYBAQAAAAGHAUAAAAABiAFAAAAAAYkBQAAAAAGKAUAAAAABiwEBAAAAAQIAAAAFACAXAADAAgAgAwAAABoAIBcAAL4CACAYAADEAgAgCQAAABoAIAoAAJUCACAQAADEAgAgZgEAyAEAIYcBQADWAQAhiAFAANYBACGMAQEAyAEAIY0BAQDIAQAhjgEBAMgBACEHCgAAlQIAIGYBAMgBACGHAUAA1gEAIYgBQADWAQAhjAEBAMgBACGNAQEAyAEAIY4BAQDIAQAhAwAAAAMAIBcAAMACACAYAADHAgAgFwAAAAMAIAMAAOYBACAHAADoAQAgCAAA6QEAIBAAAMcCACBmAQDIAQAheAAA5QGGASJ7AQDIAQAhfAEAyAEAIX0BAMgBACF-AQDhAQAhfxAA4gEAIYABEADiAQAhgQFAANYBACGCAUAA1gEAIYMBAgDjAQAhhAEQAOQBACGGAQEAyAEAIYcBQADWAQAhiAFAANYBACGJAUAA1wEAIYoBQADXAQAhiwEBAOEBACEVAwAA5gEAIAcAAOgBACAIAADpAQAgZgEAyAEAIXgAAOUBhgEiewEAyAEAIXwBAMgBACF9AQDIAQAhfgEA4QEAIX8QAOIBACGAARAA4gEAIYEBQADWAQAhggFAANYBACGDAQIA4wEAIYQBEADkAQAhhgEBAMgBACGHAUAA1gEAIYgBQADWAQAhiQFAANcBACGKAUAA1wEAIYsBAQDhAQAhFQMAAI4CACAGAACPAgAgCAAAkQIAIGYBAAAAAXgAAACGAQJ7AQAAAAF8AQAAAAF9AQAAAAF-AQAAAAF_EAAAAAGAARAAAAABgQFAAAAAAYIBQAAAAAGDAQIAAAABhAEQAAAAAYYBAQAAAAGHAUAAAAABiAFAAAAAAYkBQAAAAAGKAUAAAAABiwEBAAAAAQIAAAAFACAXAADIAgAgAwAAAAMAIBcAAMgCACAYAADMAgAgFwAAAAMAIAMAAOYBACAGAADnAQAgCAAA6QEAIBAAAMwCACBmAQDIAQAheAAA5QGGASJ7AQDIAQAhfAEAyAEAIX0BAMgBACF-AQDhAQAhfxAA4gEAIYABEADiAQAhgQFAANYBACGCAUAA1gEAIYMBAgDjAQAhhAEQAOQBACGGAQEAyAEAIYcBQADWAQAhiAFAANYBACGJAUAA1wEAIYoBQADXAQAhiwEBAOEBACEVAwAA5gEAIAYAAOcBACAIAADpAQAgZgEAyAEAIXgAAOUBhgEiewEAyAEAIXwBAMgBACF9AQDIAQAhfgEA4QEAIX8QAOIBACGAARAA4gEAIYEBQADWAQAhggFAANYBACGDAQIA4wEAIYQBEADkAQAhhgEBAMgBACGHAUAA1gEAIYgBQADWAQAhiQFAANcBACGKAUAA1wEAIYsBAQDhAQAhFQMAAI4CACAGAACPAgAgBwAAkAIAIGYBAAAAAXgAAACGAQJ7AQAAAAF8AQAAAAF9AQAAAAF-AQAAAAF_EAAAAAGAARAAAAABgQFAAAAAAYIBQAAAAAGDAQIAAAABhAEQAAAAAYYBAQAAAAGHAUAAAAABiAFAAAAAAYkBQAAAAAGKAUAAAAABiwEBAAAAAQIAAAAFACAXAADNAgAgAwAAAAMAIBcAAM0CACAYAADRAgAgFwAAAAMAIAMAAOYBACAGAADnAQAgBwAA6AEAIBAAANECACBmAQDIAQAheAAA5QGGASJ7AQDIAQAhfAEAyAEAIX0BAMgBACF-AQDhAQAhfxAA4gEAIYABEADiAQAhgQFAANYBACGCAUAA1gEAIYMBAgDjAQAhhAEQAOQBACGGAQEAyAEAIYcBQADWAQAhiAFAANYBACGJAUAA1wEAIYoBQADXAQAhiwEBAOEBACEVAwAA5gEAIAYAAOcBACAHAADoAQAgZgEAyAEAIXgAAOUBhgEiewEAyAEAIXwBAMgBACF9AQDIAQAhfgEA4QEAIX8QAOIBACGAARAA4gEAIYEBQADWAQAhggFAANYBACGDAQIA4wEAIYQBEADkAQAhhgEBAMgBACGHAUAA1gEAIYgBQADWAQAhiQFAANcBACGKAUAA1wEAIYsBAQDhAQAhAwYWAwkABwoGAgUDAAEGCgMHDgQIEgUJAAYCBAACBQABAQQAAgEEAAIDBhMABxQACBUAAgYYAAoXAAAAAAMJAAwdAA0eAA4AAAADCQAMHQANHgAOAQMAAQEDAAEFCQATHQAWHgAXLwAUMAAVAAAAAAAFCQATHQAWHgAXLwAUMAAVAgQAAgUAAQIEAAIFAAEDCQAcHQAdHgAeAAAAAwkAHB0AHR4AHgEEAAIBBAACAwkAIx0AJB4AJQAAAAMJACMdACQeACUBBAACAQQAAgMJACodACseACwAAAADCQAqHQArHgAsCwIBDBkBDRwBDh0BDx4BESABEiIIEyMJFCUBFScIFigKGSkBGioBGysIHy4LIC8PITACIjECIzICJDMCJTQCJjYCJzgIKDkQKTsCKj0IKz4RLD8CLUACLkEIMUQSMkUYM0YDNEcDNUgDNkkDN0oDOEwDOU4IOk8ZO1EDPFMIPVQaPlUDP1YDQFcIQVobQlsfQ1wERF0ERV4ERl8ER2AESGIESWQISmUgS2cETGkITWohTmsET2wEUG0IUXAiUnEmU3IFVHMFVXQFVnUFV3YFWHgFWXoIWnsnW30FXH8IXYABKF6BAQVfggEFYIMBCGGGASlihwEt"
+}
+
+async function decodeBase64AsWasm(wasmBase64: string): Promise {
+ const { Buffer } = await import('node:buffer')
+ const wasmArray = Buffer.from(wasmBase64, 'base64')
+ return new WebAssembly.Module(wasmArray)
+}
+
+config.compilerWasm = {
+ getRuntime: async () => await import("@prisma/client/runtime/query_compiler_fast_bg.postgresql.mjs"),
+
+ getQueryCompilerWasmModule: async () => {
+ const { wasm } = await import("@prisma/client/runtime/query_compiler_fast_bg.postgresql.wasm-base64.mjs")
+ return await decodeBase64AsWasm(wasm)
+ },
+
+ importName: "./query_compiler_fast_bg.js"
+}
+
+
+
+export type LogOptions =
+ 'log' extends keyof ClientOptions ? ClientOptions['log'] extends Array ? Prisma.GetEvents : never : never
+
+export interface PrismaClientConstructor {
+ /**
+ * ## Prisma Client
+ *
+ * Type-safe database client for TypeScript
+ * @example
+ * ```
+ * const prisma = new PrismaClient({
+ * adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL })
+ * })
+ * // Fetch zero or more Users
+ * const users = await prisma.user.findMany()
+ * ```
+ *
+ * Read more in our [docs](https://pris.ly/d/client).
+ */
+
+ new <
+ Options extends Prisma.PrismaClientOptions = Prisma.PrismaClientOptions,
+ LogOpts extends LogOptions = LogOptions,
+ OmitOpts extends Prisma.PrismaClientOptions['omit'] = Options extends { omit: infer U } ? U : Prisma.PrismaClientOptions['omit'],
+ ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
+ >(options: Prisma.PrismaClientConstructorArgs): PrismaClient
+}
+
+/**
+ * ## Prisma Client
+ *
+ * Type-safe database client for TypeScript
+ * @example
+ * ```
+ * const prisma = new PrismaClient({
+ * adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL })
+ * })
+ * // Fetch zero or more Users
+ * const users = await prisma.user.findMany()
+ * ```
+ *
+ * Read more in our [docs](https://pris.ly/d/client).
+ */
+
+export interface PrismaClient<
+ in LogOpts extends Prisma.LogLevel = never,
+ in out OmitOpts extends Prisma.PrismaClientOptions['omit'] = Prisma.PrismaClientOptions['omit'],
+ in out ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
+> {
+ [K: symbol]: { types: Prisma.TypeMap['other'] }
+
+ $on(eventType: V, callback: (event: V extends 'query' ? Prisma.QueryEvent : Prisma.LogEvent) => void): PrismaClient;
+
+ /**
+ * Connect with the database
+ */
+ $connect(): runtime.Types.Utils.JsPromise;
+
+ /**
+ * Disconnect from the database
+ */
+ $disconnect(): runtime.Types.Utils.JsPromise;
+
+/**
+ * Executes a prepared raw query and returns the number of affected rows.
+ * @example
+ * ```
+ * const result = await prisma.$executeRaw`UPDATE User SET cool = ${true} WHERE email = ${'user@email.com'};`
+ * ```
+ *
+ * Read more in our [docs](https://pris.ly/d/raw-queries).
+ */
+ $executeRaw(query: TemplateStringsArray | Prisma.Sql, ...values: any[]): Prisma.PrismaPromise;
+
+ /**
+ * Executes a raw query and returns the number of affected rows.
+ * Susceptible to SQL injections, see documentation.
+ * @example
+ * ```
+ * const result = await prisma.$executeRawUnsafe('UPDATE User SET cool = $1 WHERE email = $2 ;', true, 'user@email.com')
+ * ```
+ *
+ * Read more in our [docs](https://pris.ly/d/raw-queries).
+ */
+ $executeRawUnsafe(query: string, ...values: any[]): Prisma.PrismaPromise;
+
+ /**
+ * Performs a prepared raw query and returns the `SELECT` data.
+ * @example
+ * ```
+ * const result = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1} OR email = ${'user@email.com'};`
+ * ```
+ *
+ * Read more in our [docs](https://pris.ly/d/raw-queries).
+ */
+ $queryRaw(query: TemplateStringsArray | Prisma.Sql, ...values: any[]): Prisma.PrismaPromise;
+
+ /**
+ * Performs a raw query and returns the `SELECT` data.
+ * Susceptible to SQL injections, see documentation.
+ * @example
+ * ```
+ * const result = await prisma.$queryRawUnsafe('SELECT * FROM User WHERE id = $1 OR email = $2;', 1, 'user@email.com')
+ * ```
+ *
+ * Read more in our [docs](https://pris.ly/d/raw-queries).
+ */
+ $queryRawUnsafe(query: string, ...values: any[]): Prisma.PrismaPromise;
+
+
+ /**
+ * Allows the running of a sequence of read/write operations that are guaranteed to either succeed or fail as a whole.
+ * @example
+ * ```
+ * const [george, bob, alice] = await prisma.$transaction([
+ * prisma.user.create({ data: { name: 'George' } }),
+ * prisma.user.create({ data: { name: 'Bob' } }),
+ * prisma.user.create({ data: { name: 'Alice' } }),
+ * ])
+ * ```
+ *
+ * Read more in our [docs](https://www.prisma.io/docs/orm/prisma-client/queries/transactions).
+ */
+ $transaction[]>(arg: [...P], options?: { maxWait?: number, timeout?: number, isolationLevel?: Prisma.TransactionIsolationLevel }): runtime.Types.Utils.JsPromise>
+
+ $transaction(fn: (prisma: Omit) => runtime.Types.Utils.JsPromise, options?: { maxWait?: number, timeout?: number, isolationLevel?: Prisma.TransactionIsolationLevel }): runtime.Types.Utils.JsPromise
+
+ $extends: runtime.Types.Extensions.ExtendsHook<"extends", Prisma.TypeMapCb, ExtArgs, runtime.Types.Utils.Call, {
+ extArgs: ExtArgs
+ }>>
+
+ /**
+ * `prisma.user`: Exposes CRUD operations for the **User** model.
+ * Example usage:
+ * ```ts
+ * // Fetch zero or more Users
+ * const users = await prisma.user.findMany()
+ * ```
+ */
+ get user(): Prisma.UserDelegate;
+
+ /**
+ * `prisma.bounty`: Exposes CRUD operations for the **Bounty** model.
+ * Example usage:
+ * ```ts
+ * // Fetch zero or more Bounties
+ * const bounties = await prisma.bounty.findMany()
+ * ```
+ */
+ get bounty(): Prisma.BountyDelegate;
+
+ /**
+ * `prisma.bountyVolunteer`: Exposes CRUD operations for the **BountyVolunteer** model.
+ * Example usage:
+ * ```ts
+ * // Fetch zero or more BountyVolunteers
+ * const bountyVolunteers = await prisma.bountyVolunteer.findMany()
+ * ```
+ */
+ get bountyVolunteer(): Prisma.BountyVolunteerDelegate;
+
+ /**
+ * `prisma.bountySkillRequirement`: Exposes CRUD operations for the **BountySkillRequirement** model.
+ * Example usage:
+ * ```ts
+ * // Fetch zero or more BountySkillRequirements
+ * const bountySkillRequirements = await prisma.bountySkillRequirement.findMany()
+ * ```
+ */
+ get bountySkillRequirement(): Prisma.BountySkillRequirementDelegate;
+
+ /**
+ * `prisma.bountyEquipmentRequirement`: Exposes CRUD operations for the **BountyEquipmentRequirement** model.
+ * Example usage:
+ * ```ts
+ * // Fetch zero or more BountyEquipmentRequirements
+ * const bountyEquipmentRequirements = await prisma.bountyEquipmentRequirement.findMany()
+ * ```
+ */
+ get bountyEquipmentRequirement(): Prisma.BountyEquipmentRequirementDelegate;
+}
+
+export function getPrismaClientClass(): PrismaClientConstructor {
+ return runtime.getPrismaClient(config) as unknown as PrismaClientConstructor
+}
diff --git a/generated/prisma/internal/prismaNamespace.ts b/generated/prisma/internal/prismaNamespace.ts
new file mode 100644
index 0000000..2ef0013
--- /dev/null
+++ b/generated/prisma/internal/prismaNamespace.ts
@@ -0,0 +1,1259 @@
+
+/* !!! This is code generated by Prisma. Do not edit directly. !!! */
+/* eslint-disable */
+// biome-ignore-all lint: generated file
+// @ts-nocheck
+/*
+ * WARNING: This is an internal file that is subject to change!
+ *
+ * 🛑 Under no circumstances should you import this file directly! 🛑
+ *
+ * All exports from this file are wrapped under a `Prisma` namespace object in the client.ts file.
+ * While this enables partial backward compatibility, it is not part of the stable public API.
+ *
+ * If you are looking for your Models, Enums, and Input Types, please import them from the respective
+ * model files in the `model` directory!
+ */
+
+import * as runtime from "@prisma/client/runtime/client"
+import type * as Prisma from "../models"
+import { type PrismaClient } from "./class"
+
+export type * from '../models'
+
+export type DMMF = typeof runtime.DMMF
+
+export type PrismaPromise = runtime.Types.Public.PrismaPromise
+
+/**
+ * Prisma Errors
+ */
+
+export const PrismaClientKnownRequestError = runtime.PrismaClientKnownRequestError
+export type PrismaClientKnownRequestError = runtime.PrismaClientKnownRequestError
+
+export const PrismaClientUnknownRequestError = runtime.PrismaClientUnknownRequestError
+export type PrismaClientUnknownRequestError = runtime.PrismaClientUnknownRequestError
+
+export const PrismaClientRustPanicError = runtime.PrismaClientRustPanicError
+export type PrismaClientRustPanicError = runtime.PrismaClientRustPanicError
+
+export const PrismaClientInitializationError = runtime.PrismaClientInitializationError
+export type PrismaClientInitializationError = runtime.PrismaClientInitializationError
+
+export const PrismaClientValidationError = runtime.PrismaClientValidationError
+export type PrismaClientValidationError = runtime.PrismaClientValidationError
+
+/**
+ * Re-export of sql-template-tag
+ */
+export const sql = runtime.sqltag
+export const empty = runtime.empty
+export const join = runtime.join
+export const raw = runtime.raw
+export const Sql = runtime.Sql
+export type Sql = runtime.Sql
+
+
+
+/**
+ * Decimal.js
+ */
+export const Decimal = runtime.Decimal
+export type Decimal = runtime.Decimal
+
+export type DecimalJsLike = runtime.DecimalJsLike
+
+/**
+* Extensions
+*/
+export type Extension = runtime.Types.Extensions.UserArgs
+export const getExtensionContext = runtime.Extensions.getExtensionContext
+export type Args = runtime.Types.Public.Args
+export type Payload = runtime.Types.Public.Payload
+export type Result = runtime.Types.Public.Result
+export type Exact = runtime.Types.Public.Exact
+
+export type PrismaVersion = {
+ client: string
+ engine: string
+}
+
+/**
+ * Prisma Client JS version: 7.10.0
+ * Query Engine version: 0edf323efd1d98336f3f0a68684b56f689b900d3
+ */
+export const prismaVersion: PrismaVersion = {
+ client: "7.10.0",
+ engine: "0edf323efd1d98336f3f0a68684b56f689b900d3"
+}
+
+/**
+ * Utility Types
+ */
+
+export type Bytes = runtime.Bytes
+export type JsonObject = runtime.JsonObject
+export type JsonArray = runtime.JsonArray
+export type JsonValue = runtime.JsonValue
+export type InputJsonObject = runtime.InputJsonObject
+export type InputJsonArray = runtime.InputJsonArray
+export type InputJsonValue = runtime.InputJsonValue
+
+
+export const NullTypes = {
+ DbNull: runtime.NullTypes.DbNull as (new (secret: never) => typeof runtime.DbNull),
+ JsonNull: runtime.NullTypes.JsonNull as (new (secret: never) => typeof runtime.JsonNull),
+ AnyNull: runtime.NullTypes.AnyNull as (new (secret: never) => typeof runtime.AnyNull),
+}
+/**
+ * Helper for filtering JSON entries that have `null` on the database (empty on the db)
+ *
+ * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
+ */
+export const DbNull = runtime.DbNull
+
+/**
+ * Helper for filtering JSON entries that have JSON `null` values (not empty on the db)
+ *
+ * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
+ */
+export const JsonNull = runtime.JsonNull
+
+/**
+ * Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull`
+ *
+ * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
+ */
+export const AnyNull = runtime.AnyNull
+
+
+type SelectAndInclude = {
+ select: any
+ include: any
+}
+
+type SelectAndOmit = {
+ select: any
+ omit: any
+}
+
+/**
+ * From T, pick a set of properties whose keys are in the union K
+ */
+type Prisma__Pick = {
+ [P in K]: T[P];
+};
+
+export type Enumerable = T | Array;
+
+/**
+ * Subset
+ * @desc From `T` pick properties that exist in `U`. Simple version of Intersection
+ */
+export type Subset = {
+ [key in keyof T]: key extends keyof U ? T[key] : never;
+};
+
+/**
+ * Resolved type of the argument passed to the `PrismaClient` constructor.
+ *
+ * When called without a narrower options type (the common case), this resolves
+ * to `PrismaClientOptions` directly, which produces a clear TypeScript error
+ * message (`not assignable to parameter of type 'PrismaClientOptions'`) when
+ * the argument is missing or incomplete. When the user supplies a narrower
+ * options type (e.g. via a literal), it falls back to `Subset` to keep
+ * filtering out unknown properties.
+ */
+export type PrismaClientConstructorArgs =
+ [PrismaClientOptions] extends [Options] ? PrismaClientOptions : Subset;
+
+/**
+ * SelectSubset
+ * @desc From `T` pick properties that exist in `U`. Simple version of Intersection.
+ * Additionally, it validates, if both select and include are present. If the case, it errors.
+ */
+export type SelectSubset = {
+ [key in keyof T]: key extends keyof U ? T[key] : never
+} &
+ (T extends SelectAndInclude
+ ? 'Please either choose `select` or `include`.'
+ : T extends SelectAndOmit
+ ? 'Please either choose `select` or `omit`.'
+ : {})
+
+/**
+ * Subset + Intersection
+ * @desc From `T` pick properties that exist in `U` and intersect `K`
+ */
+export type SubsetIntersection = {
+ [key in keyof T]: key extends keyof U ? T[key] : never
+} &
+ K
+
+type Without = { [P in Exclude]?: never };
+
+/**
+ * XOR is needed to have a real mutually exclusive union type
+ * https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types
+ */
+export type XOR =
+ T extends object ?
+ U extends object ?
+ ((Without & U) | (Without & T)) & object
+ : U : T
+
+
+/**
+ * Is T a Record?
+ */
+type IsObject = T extends Array
+? False
+: T extends Date
+? False
+: T extends Uint8Array
+? False
+: T extends BigInt
+? False
+: T extends object
+? True
+: False
+
+
+/**
+ * If it's T[], return T
+ */
+export type UnEnumerate = T extends Array ? U : T
+
+/**
+ * From ts-toolbelt
+ */
+
+type __Either = Omit &
+ {
+ // Merge all but K
+ [P in K]: Prisma__Pick // With K possibilities
+ }[K]
+
+type EitherStrict = Strict<__Either>
+
+type EitherLoose = ComputeRaw<__Either>
+
+type _Either<
+ O extends object,
+ K extends Key,
+ strict extends Boolean
+> = {
+ 1: EitherStrict
+ 0: EitherLoose
+}[strict]
+
+export type Either<
+ O extends object,
+ K extends Key,
+ strict extends Boolean = 1
+> = O extends unknown ? _Either : never
+
+export type Union = any
+
+export type PatchUndefined = {
+ [K in keyof O]: O[K] extends undefined ? At : O[K]
+} & {}
+
+/** Helper Types for "Merge" **/
+export type IntersectOf = (
+ U extends unknown ? (k: U) => void : never
+) extends (k: infer I) => void
+ ? I
+ : never
+
+export type Overwrite = {
+ [K in keyof O]: K extends keyof O1 ? O1[K] : O[K];
+} & {};
+
+type _Merge = IntersectOf;
+}>>;
+
+type Key = string | number | symbol;
+type AtStrict = O[K & keyof O];
+type AtLoose = O extends unknown ? AtStrict : never;
+export type At = {
+ 1: AtStrict;
+ 0: AtLoose;
+}[strict];
+
+export type ComputeRaw = A extends Function ? A : {
+ [K in keyof A]: A[K];
+} & {};
+
+export type OptionalFlat = {
+ [K in keyof O]?: O[K];
+} & {};
+
+type _Record = {
+ [P in K]: T;
+};
+
+// cause typescript not to expand types and preserve names
+type NoExpand = T extends unknown ? T : never;
+
+// this type assumes the passed object is entirely optional
+export type AtLeast = NoExpand<
+ O extends unknown
+ ? | (K extends keyof O ? { [P in K]: O[P] } & O : O)
+ | {[P in keyof O as P extends K ? P : never]-?: O[P]} & O
+ : never>;
+
+type _Strict = U extends unknown ? U & OptionalFlat<_Record, keyof U>, never>> : never;
+
+export type Strict = ComputeRaw<_Strict>;
+/** End Helper Types for "Merge" **/
+
+export type Merge = ComputeRaw<_Merge>>;
+
+export type Boolean = True | False
+
+export type True = 1
+
+export type False = 0
+
+export type Not = {
+ 0: 1
+ 1: 0
+}[B]
+
+export type Extends = [A1] extends [never]
+ ? 0 // anything `never` is false
+ : A1 extends A2
+ ? 1
+ : 0
+
+export type Has = Not<
+ Extends, U1>
+>
+
+export type Or = {
+ 0: {
+ 0: 0
+ 1: 1
+ }
+ 1: {
+ 0: 1
+ 1: 1
+ }
+}[B1][B2]
+
+export type Keys = U extends unknown ? keyof U : never
+
+export type GetScalarType = O extends object ? {
+ [P in keyof T]: P extends keyof O
+ ? O[P]
+ : never
+} : never
+
+type FieldPaths<
+ T,
+ U = Omit
+> = IsObject extends True ? U : T
+
+export type GetHavingFields = {
+ [K in keyof T]: Or<
+ Or, Extends<'AND', K>>,
+ Extends<'NOT', K>
+ > extends True
+ ? // infer is only needed to not hit TS limit
+ // based on the brilliant idea of Pierre-Antoine Mills
+ // https://github.com/microsoft/TypeScript/issues/30188#issuecomment-478938437
+ T[K] extends infer TK
+ ? GetHavingFields extends object ? Merge> : never>
+ : never
+ : {} extends FieldPaths
+ ? never
+ : K
+}[keyof T]
+
+/**
+ * Convert tuple to union
+ */
+type _TupleToUnion = T extends (infer E)[] ? E : never
+type TupleToUnion = _TupleToUnion
+export type MaybeTupleToUnion = T extends any[] ? TupleToUnion : T
+
+/**
+ * Like `Pick`, but additionally can also accept an array of keys
+ */
+export type PickEnumerable | keyof T> = Prisma__Pick>
+
+/**
+ * Exclude all keys with underscores
+ */
+export type ExcludeUnderscoreKeys = T extends `_${string}` ? never : T
+
+
+export type FieldRef = runtime.FieldRef
+
+type FieldRefInputType = Model extends never ? never : FieldRef
+
+
+export const ModelName = {
+ User: 'User',
+ Bounty: 'Bounty',
+ BountyVolunteer: 'BountyVolunteer',
+ BountySkillRequirement: 'BountySkillRequirement',
+ BountyEquipmentRequirement: 'BountyEquipmentRequirement'
+} as const
+
+export type ModelName = (typeof ModelName)[keyof typeof ModelName]
+
+
+
+export interface TypeMapCb extends runtime.Types.Utils.Fn<{extArgs: runtime.Types.Extensions.InternalArgs }, runtime.Types.Utils.Record> {
+ returns: TypeMap
+}
+
+export type TypeMap = {
+ globalOmitOptions: {
+ omit: GlobalOmitOptions
+ }
+ meta: {
+ modelProps: "user" | "bounty" | "bountyVolunteer" | "bountySkillRequirement" | "bountyEquipmentRequirement"
+ txIsolationLevel: TransactionIsolationLevel
+ }
+ model: {
+ User: {
+ payload: Prisma.$UserPayload
+ fields: Prisma.UserFieldRefs
+ operations: {
+ findUnique: {
+ args: Prisma.UserFindUniqueArgs
+ result: runtime.Types.Utils.PayloadToResult | null
+ }
+ findUniqueOrThrow: {
+ args: Prisma.UserFindUniqueOrThrowArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ findFirst: {
+ args: Prisma.UserFindFirstArgs
+ result: runtime.Types.Utils.PayloadToResult | null
+ }
+ findFirstOrThrow: {
+ args: Prisma.UserFindFirstOrThrowArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ findMany: {
+ args: Prisma.UserFindManyArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ create: {
+ args: Prisma.UserCreateArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ createMany: {
+ args: Prisma.UserCreateManyArgs
+ result: BatchPayload
+ }
+ createManyAndReturn: {
+ args: Prisma.UserCreateManyAndReturnArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ delete: {
+ args: Prisma.UserDeleteArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ update: {
+ args: Prisma.UserUpdateArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ deleteMany: {
+ args: Prisma.UserDeleteManyArgs
+ result: BatchPayload
+ }
+ updateMany: {
+ args: Prisma.UserUpdateManyArgs
+ result: BatchPayload
+ }
+ updateManyAndReturn: {
+ args: Prisma.UserUpdateManyAndReturnArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ upsert: {
+ args: Prisma.UserUpsertArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ aggregate: {
+ args: Prisma.UserAggregateArgs
+ result: runtime.Types.Utils.Optional
+ }
+ groupBy: {
+ args: Prisma.UserGroupByArgs
+ result: runtime.Types.Utils.Optional[]
+ }
+ count: {
+ args: Prisma.UserCountArgs
+ result: runtime.Types.Utils.Optional | number
+ }
+ }
+ }
+ Bounty: {
+ payload: Prisma.$BountyPayload
+ fields: Prisma.BountyFieldRefs
+ operations: {
+ findUnique: {
+ args: Prisma.BountyFindUniqueArgs
+ result: runtime.Types.Utils.PayloadToResult | null
+ }
+ findUniqueOrThrow: {
+ args: Prisma.BountyFindUniqueOrThrowArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ findFirst: {
+ args: Prisma.BountyFindFirstArgs
+ result: runtime.Types.Utils.PayloadToResult | null
+ }
+ findFirstOrThrow: {
+ args: Prisma.BountyFindFirstOrThrowArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ findMany: {
+ args: Prisma.BountyFindManyArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ create: {
+ args: Prisma.BountyCreateArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ createMany: {
+ args: Prisma.BountyCreateManyArgs
+ result: BatchPayload
+ }
+ createManyAndReturn: {
+ args: Prisma.BountyCreateManyAndReturnArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ delete: {
+ args: Prisma.BountyDeleteArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ update: {
+ args: Prisma.BountyUpdateArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ deleteMany: {
+ args: Prisma.BountyDeleteManyArgs
+ result: BatchPayload
+ }
+ updateMany: {
+ args: Prisma.BountyUpdateManyArgs
+ result: BatchPayload
+ }
+ updateManyAndReturn: {
+ args: Prisma.BountyUpdateManyAndReturnArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ upsert: {
+ args: Prisma.BountyUpsertArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ aggregate: {
+ args: Prisma.BountyAggregateArgs
+ result: runtime.Types.Utils.Optional
+ }
+ groupBy: {
+ args: Prisma.BountyGroupByArgs
+ result: runtime.Types.Utils.Optional[]
+ }
+ count: {
+ args: Prisma.BountyCountArgs
+ result: runtime.Types.Utils.Optional | number
+ }
+ }
+ }
+ BountyVolunteer: {
+ payload: Prisma.$BountyVolunteerPayload
+ fields: Prisma.BountyVolunteerFieldRefs
+ operations: {
+ findUnique: {
+ args: Prisma.BountyVolunteerFindUniqueArgs
+ result: runtime.Types.Utils.PayloadToResult | null
+ }
+ findUniqueOrThrow: {
+ args: Prisma.BountyVolunteerFindUniqueOrThrowArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ findFirst: {
+ args: Prisma.BountyVolunteerFindFirstArgs
+ result: runtime.Types.Utils.PayloadToResult | null
+ }
+ findFirstOrThrow: {
+ args: Prisma.BountyVolunteerFindFirstOrThrowArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ findMany: {
+ args: Prisma.BountyVolunteerFindManyArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ create: {
+ args: Prisma.BountyVolunteerCreateArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ createMany: {
+ args: Prisma.BountyVolunteerCreateManyArgs
+ result: BatchPayload
+ }
+ createManyAndReturn: {
+ args: Prisma.BountyVolunteerCreateManyAndReturnArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ delete: {
+ args: Prisma.BountyVolunteerDeleteArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ update: {
+ args: Prisma.BountyVolunteerUpdateArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ deleteMany: {
+ args: Prisma.BountyVolunteerDeleteManyArgs
+ result: BatchPayload
+ }
+ updateMany: {
+ args: Prisma.BountyVolunteerUpdateManyArgs
+ result: BatchPayload
+ }
+ updateManyAndReturn: {
+ args: Prisma.BountyVolunteerUpdateManyAndReturnArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ upsert: {
+ args: Prisma.BountyVolunteerUpsertArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ aggregate: {
+ args: Prisma.BountyVolunteerAggregateArgs
+ result: runtime.Types.Utils.Optional
+ }
+ groupBy: {
+ args: Prisma.BountyVolunteerGroupByArgs
+ result: runtime.Types.Utils.Optional[]
+ }
+ count: {
+ args: Prisma.BountyVolunteerCountArgs
+ result: runtime.Types.Utils.Optional | number
+ }
+ }
+ }
+ BountySkillRequirement: {
+ payload: Prisma.$BountySkillRequirementPayload
+ fields: Prisma.BountySkillRequirementFieldRefs
+ operations: {
+ findUnique: {
+ args: Prisma.BountySkillRequirementFindUniqueArgs
+ result: runtime.Types.Utils.PayloadToResult | null
+ }
+ findUniqueOrThrow: {
+ args: Prisma.BountySkillRequirementFindUniqueOrThrowArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ findFirst: {
+ args: Prisma.BountySkillRequirementFindFirstArgs
+ result: runtime.Types.Utils.PayloadToResult | null
+ }
+ findFirstOrThrow: {
+ args: Prisma.BountySkillRequirementFindFirstOrThrowArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ findMany: {
+ args: Prisma.BountySkillRequirementFindManyArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ create: {
+ args: Prisma.BountySkillRequirementCreateArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ createMany: {
+ args: Prisma.BountySkillRequirementCreateManyArgs
+ result: BatchPayload
+ }
+ createManyAndReturn: {
+ args: Prisma.BountySkillRequirementCreateManyAndReturnArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ delete: {
+ args: Prisma.BountySkillRequirementDeleteArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ update: {
+ args: Prisma.BountySkillRequirementUpdateArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ deleteMany: {
+ args: Prisma.BountySkillRequirementDeleteManyArgs
+ result: BatchPayload
+ }
+ updateMany: {
+ args: Prisma.BountySkillRequirementUpdateManyArgs
+ result: BatchPayload
+ }
+ updateManyAndReturn: {
+ args: Prisma.BountySkillRequirementUpdateManyAndReturnArgs
+ result: runtime.Types.Utils.PayloadToResult[]
+ }
+ upsert: {
+ args: Prisma.BountySkillRequirementUpsertArgs
+ result: runtime.Types.Utils.PayloadToResult
+ }
+ aggregate: {
+ args: Prisma.BountySkillRequirementAggregateArgs
+ result: runtime.Types.Utils.Optional
+ }
+ groupBy: {
+ args: Prisma.BountySkillRequirementGroupByArgs
+ result: runtime.Types.Utils.Optional[]
+ }
+ count: {
+ args: Prisma.BountySkillRequirementCountArgs
+ result: runtime.Types.Utils.Optional