change selfie with ktp to selfie with setrip tag
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"WebFetch(domain:unsplash.com)"
|
"WebFetch(domain:unsplash.com)",
|
||||||
|
"Bash(npx prisma *)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ yarn-error.log*
|
|||||||
# env files (can opt-in for committing if needed)
|
# env files (can opt-in for committing if needed)
|
||||||
.env*
|
.env*
|
||||||
|
|
||||||
# private uploads (KYC: KTP / selfie). Never serve directly.
|
# private uploads (KYC: KTP / liveness). Never serve directly.
|
||||||
/uploads/
|
/uploads/
|
||||||
|
|
||||||
# vercel
|
# vercel
|
||||||
|
|||||||
+1
-1
@@ -236,7 +236,7 @@ Alur data mengikuti pola yang sama: **UI (`app/`) → server actions (`features/
|
|||||||
|
|
||||||
### Verifikasi organizer (KYC ringan)
|
### Verifikasi organizer (KYC ringan)
|
||||||
|
|
||||||
- Model `OrganizerVerification` (1-1 ke `User`) menyimpan KTP (nama, NIK unik, tanggal lahir, alamat), URL foto KTP & selfie, data rekening bank, dan status `PENDING` / `APPROVED` / `REJECTED` + audit reviewer.
|
- Model `OrganizerVerification` (1-1 ke `User`) menyimpan KTP (nama, NIK unik, tanggal lahir, alamat), storage key foto KTP & foto liveness (user memegang kertas tulisan "SETRIP" sebagai bukti pengajuan), data rekening bank, dan status `PENDING` / `APPROVED` / `REJECTED` + audit reviewer.
|
||||||
- Alur: user submit di `/verify` (`features/organizer/`) → admin review di `/admin/verifications` → setujui/tolak.
|
- Alur: user submit di `/verify` (`features/organizer/`) → admin review di `/admin/verifications` → setujui/tolak.
|
||||||
- **Gate trip berbayar:** `createTripAction` menolak `price > 0` jika user belum `APPROVED` (`organizerService.isApproved`).
|
- **Gate trip berbayar:** `createTripAction` menolak `price > 0` jika user belum `APPROVED` (`organizerService.isApproved`).
|
||||||
- **Akses admin:** `lib/admin.ts → isAdminEmail()` membaca `ADMIN_EMAILS` (env, comma-separated).
|
- **Akses admin:** `lib/admin.ts → isAdminEmail()` membaca `ADMIN_EMAILS` (env, comma-separated).
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Tanpa login, pengguna tetap bisa melihat daftar trip dan detail trip, tetapi tid
|
|||||||
|
|
||||||
Organizer **tidak** bisa join trip sendiri; di detail trip ditampilkan bahwa dia adalah organizer trip ini.
|
Organizer **tidak** bisa join trip sendiri; di detail trip ditampilkan bahwa dia adalah organizer trip ini.
|
||||||
|
|
||||||
**Verifikasi organizer (untuk trip berbayar).** Trip dengan harga > 0 hanya bisa dibuat oleh user yang sudah mengirim KTP, selfie, dan data rekening di `/verify` lalu disetujui admin di `/admin/verifications`. Trip gratis tidak butuh verifikasi. Organizer yang sudah disetujui tampil dengan badge **✅ Verified Organizer** di halaman detail trip.
|
**Verifikasi organizer (untuk trip berbayar).** Trip dengan harga > 0 hanya bisa dibuat oleh user yang sudah mengirim KTP, foto liveness (memegang kertas tulisan "SETRIP"), dan data rekening di `/verify` lalu disetujui admin di `/admin/verifications`. Trip gratis tidak butuh verifikasi. Organizer yang sudah disetujui tampil dengan badge **✅ Verified Organizer** di halaman detail trip.
|
||||||
|
|
||||||
### 3. Peserta: mencari trip
|
### 3. Peserta: mencari trip
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ Alur ini menggambarkan satu peserta dari pertama kali mendaftar sampai pembayara
|
|||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| Trip | `Trip`: judul, gunung, lokasi, tanggal, kuota, harga, status trip (`OPEN` / `FULL` / …), meeting point, itinerary, termasuk/tidak termasuk, relasi ke organizer |
|
| Trip | `Trip`: judul, gunung, lokasi, tanggal, kuota, harga, status trip (`OPEN` / `FULL` / …), meeting point, itinerary, termasuk/tidak termasuk, relasi ke organizer |
|
||||||
| Peserta | `TripParticipant` unik per `(tripId, userId)`: status **`PENDING`** / **`CONFIRMED`** / **`CANCELLED`**, serta **`markedPaidAt`** & **`paymentConfirmedAt`** untuk alur bayar manual |
|
| Peserta | `TripParticipant` unik per `(tripId, userId)`: status **`PENDING`** / **`CONFIRMED`** / **`CANCELLED`**, serta **`markedPaidAt`** & **`paymentConfirmedAt`** untuk alur bayar manual |
|
||||||
| Organizer (kepercayaan) | `OrganizerVerification` (1-1 ke `User`) berisi KTP, selfie, rekening, dan status (`PENDING` / `APPROVED` / `REJECTED`); badge **Verified Organizer** muncul ketika `status === "APPROVED"` (helper `lib/trust.ts → isVerifiedOrganizer`). Agregat rating & jumlah trip dihitung dari ulasan & trip. |
|
| Organizer (kepercayaan) | `OrganizerVerification` (1-1 ke `User`) berisi KTP, foto liveness (memegang kertas "SETRIP"), rekening, dan status (`PENDING` / `APPROVED` / `REJECTED`); badge **Verified Organizer** muncul ketika `status === "APPROVED"` (helper `lib/trust.ts → isVerifiedOrganizer`). Agregat rating & jumlah trip dihitung dari ulasan & trip. |
|
||||||
| Persetujuan T&C / Privasi | `User.acceptedTermsAndPrivacy` + `User.acceptedAt`, dicentang saat registrasi (link ke `/terms` & `/privacy`). |
|
| Persetujuan T&C / Privasi | `User.acceptedTermsAndPrivacy` + `User.acceptedAt`, dicentang saat registrasi (link ke `/terms` & `/privacy`). |
|
||||||
|
|
||||||
## Menjalankan secara lokal
|
## Menjalankan secara lokal
|
||||||
|
|||||||
@@ -42,6 +42,26 @@ Selesai. `tsc --noEmit` lulus. Migration `20260508130000_add_trip_vibe` belum di
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Patch — KYC liveness photo rename (di luar fase social repositioning)
|
||||||
|
|
||||||
|
Mengubah foto liveness dari "selfie memegang KTP" (pola KYC standar) menjadi "memegang kertas tulisan SETRIP".
|
||||||
|
|
||||||
|
| Item | Status | File |
|
||||||
|
|---|---|---|
|
||||||
|
| Field `selfieKey` → `livenessKey` di `OrganizerVerification` | ✅ | [prisma/schema.prisma](prisma/schema.prisma), [prisma/migrations/20260508140000_rename_selfie_to_liveness/migration.sql](prisma/migrations/20260508140000_rename_selfie_to_liveness/migration.sql) |
|
||||||
|
| Storage kind `selfie` → `liveness` (path `liveness/<id>.<ext>`) | ✅ | [lib/secure-storage.ts](lib/secure-storage.ts) |
|
||||||
|
| Validasi + action + service + verify-form + review-card | ✅ | [features/organizer/schemas.ts](features/organizer/schemas.ts), [features/organizer/actions.ts](features/organizer/actions.ts), [server/services/organizer.service.ts](server/services/organizer.service.ts), [features/organizer/components/verify-form.tsx](features/organizer/components/verify-form.tsx), [features/organizer/components/review-card.tsx](features/organizer/components/review-card.tsx) |
|
||||||
|
| API routes `/api/upload/kyc` & `/api/files/kyc/[id]/[kind]` | ✅ | [app/api/upload/kyc/route.ts](app/api/upload/kyc/route.ts), [app/api/files/kyc/[id]/[kind]/route.ts](app/api/files/kyc/%5Bid%5D/%5Bkind%5D/route.ts) |
|
||||||
|
| Halaman verify, admin, seed, README, ARCHITECTURE | ✅ | [app/verify/page.tsx](app/verify/page.tsx), [app/admin/verifications/page.tsx](app/admin/verifications/page.tsx), [app/create-trip/page.tsx](app/create-trip/page.tsx), [prisma/seed.ts](prisma/seed.ts), [README.md](README.md), [ARCHITECTURE.md](ARCHITECTURE.md) |
|
||||||
|
|
||||||
|
**Trade-off keamanan yang sudah dikomunikasikan:** pola "selfie + KTP" lebih kuat (membuktikan KTP fisik di tangan pemilik). Pola "selfie + kertas SETRIP" lebih lemah dari sisi binding KTP↔orang, tapi mengurangi paparan KTP user dan masih mencegah replay dari platform lain. Risiko fraud naik sedikit — tetap dipilih atas request user.
|
||||||
|
|
||||||
|
**Catatan migrasi data lama:** kolom DB di-rename, tapi nilai-nilai key lama masih punya prefix `selfie/` (mis. `selfie/abc.jpg`). Setelah migration di-apply, validasi schema menolak prefix lama → user dengan pengajuan PENDING perlu re-upload foto liveness baru. Folder fisik `uploads/private/selfie/` tidak dipakai lagi, bisa dihapus manual setelah konfirmasi tidak ada data aktif yang merujuk.
|
||||||
|
|
||||||
|
**Tindakan manual:** jalankan `npx prisma migrate deploy` untuk apply `20260508140000_rename_selfie_to_liveness` (sekarang total 4 migration pending kalau belum pernah deploy).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Phase C — Interaksi & continuity (separate, lebih besar) ⏳
|
## Phase C — Interaksi & continuity (separate, lebih besar) ⏳
|
||||||
|
|
||||||
Belum mulai. Setiap item bisa jadi PR terpisah karena perlu schema baru + UI substansial.
|
Belum mulai. Setiap item bisa jadi PR terpisah karena perlu schema baru + UI substansial.
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ export default async function AdminVerificationsPage({ searchParams }: PageProps
|
|||||||
Review Verifikasi Organizer
|
Review Verifikasi Organizer
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-1 text-sm text-neutral-500">
|
<p className="mt-1 text-sm text-neutral-500">
|
||||||
Periksa data KTP, selfie, dan rekening sebelum menyetujui.
|
Periksa data KTP, foto liveness (memegang kertas SETRIP), dan rekening
|
||||||
|
sebelum menyetujui.
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export async function GET(_req: NextRequest, ctx: RouteCtx) {
|
|||||||
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = kind === "ktp" ? verification.ktpImageKey : verification.selfieKey;
|
const key = kind === "ktp" ? verification.ktpImageKey : verification.livenessKey;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
return NextResponse.json({ error: "File belum diunggah" }, { status: 404 });
|
return NextResponse.json({ error: "File belum diunggah" }, { status: 404 });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,10 @@ export async function POST(req: NextRequest) {
|
|||||||
const file = form.get("file");
|
const file = form.get("file");
|
||||||
|
|
||||||
if (!isKycKind(kind)) {
|
if (!isKycKind(kind)) {
|
||||||
return NextResponse.json({ error: "kind harus 'ktp' atau 'selfie'" }, { status: 400 });
|
return NextResponse.json(
|
||||||
|
{ error: "kind harus 'ktp' atau 'liveness'" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!(file instanceof File)) {
|
if (!(file instanceof File)) {
|
||||||
return NextResponse.json({ error: "File wajib diisi" }, { status: 400 });
|
return NextResponse.json({ error: "File wajib diisi" }, { status: 400 });
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ function VerificationBanner({
|
|||||||
<p className="mt-1 text-sm text-neutral-700">
|
<p className="mt-1 text-sm text-neutral-700">
|
||||||
{isRejected
|
{isRejected
|
||||||
? "Pengajuan sebelumnya ditolak. Untuk membuat trip berbayar, perbaiki data dan ajukan ulang."
|
? "Pengajuan sebelumnya ditolak. Untuk membuat trip berbayar, perbaiki data dan ajukan ulang."
|
||||||
: "Untuk membuat trip berbayar, akun kamu perlu diverifikasi (KTP, selfie, & rekening). Trip gratis tidak butuh verifikasi."}
|
: "Untuk membuat trip berbayar, akun kamu perlu diverifikasi (KTP, foto memegang kertas SETRIP, & rekening). Trip gratis tidak butuh verifikasi."}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Link
|
<Link
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1100,7 +1100,7 @@ export const OrganizerVerificationScalarFieldEnum = {
|
|||||||
birthDate: 'birthDate',
|
birthDate: 'birthDate',
|
||||||
address: 'address',
|
address: 'address',
|
||||||
ktpImageKey: 'ktpImageKey',
|
ktpImageKey: 'ktpImageKey',
|
||||||
selfieKey: 'selfieKey',
|
livenessKey: 'livenessKey',
|
||||||
bankName: 'bankName',
|
bankName: 'bankName',
|
||||||
bankAccountNumber: 'bankAccountNumber',
|
bankAccountNumber: 'bankAccountNumber',
|
||||||
bankAccountName: 'bankAccountName',
|
bankAccountName: 'bankAccountName',
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export const OrganizerVerificationScalarFieldEnum = {
|
|||||||
birthDate: 'birthDate',
|
birthDate: 'birthDate',
|
||||||
address: 'address',
|
address: 'address',
|
||||||
ktpImageKey: 'ktpImageKey',
|
ktpImageKey: 'ktpImageKey',
|
||||||
selfieKey: 'selfieKey',
|
livenessKey: 'livenessKey',
|
||||||
bankName: 'bankName',
|
bankName: 'bankName',
|
||||||
bankAccountNumber: 'bankAccountNumber',
|
bankAccountNumber: 'bankAccountNumber',
|
||||||
bankAccountName: 'bankAccountName',
|
bankAccountName: 'bankAccountName',
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export type OrganizerVerificationMinAggregateOutputType = {
|
|||||||
birthDate: Date | null
|
birthDate: Date | null
|
||||||
address: string | null
|
address: string | null
|
||||||
ktpImageKey: string | null
|
ktpImageKey: string | null
|
||||||
selfieKey: string | null
|
livenessKey: string | null
|
||||||
bankName: string | null
|
bankName: string | null
|
||||||
bankAccountNumber: string | null
|
bankAccountNumber: string | null
|
||||||
bankAccountName: string | null
|
bankAccountName: string | null
|
||||||
@@ -55,7 +55,7 @@ export type OrganizerVerificationMaxAggregateOutputType = {
|
|||||||
birthDate: Date | null
|
birthDate: Date | null
|
||||||
address: string | null
|
address: string | null
|
||||||
ktpImageKey: string | null
|
ktpImageKey: string | null
|
||||||
selfieKey: string | null
|
livenessKey: string | null
|
||||||
bankName: string | null
|
bankName: string | null
|
||||||
bankAccountNumber: string | null
|
bankAccountNumber: string | null
|
||||||
bankAccountName: string | null
|
bankAccountName: string | null
|
||||||
@@ -77,7 +77,7 @@ export type OrganizerVerificationCountAggregateOutputType = {
|
|||||||
birthDate: number
|
birthDate: number
|
||||||
address: number
|
address: number
|
||||||
ktpImageKey: number
|
ktpImageKey: number
|
||||||
selfieKey: number
|
livenessKey: number
|
||||||
bankName: number
|
bankName: number
|
||||||
bankAccountNumber: number
|
bankAccountNumber: number
|
||||||
bankAccountName: number
|
bankAccountName: number
|
||||||
@@ -101,7 +101,7 @@ export type OrganizerVerificationMinAggregateInputType = {
|
|||||||
birthDate?: true
|
birthDate?: true
|
||||||
address?: true
|
address?: true
|
||||||
ktpImageKey?: true
|
ktpImageKey?: true
|
||||||
selfieKey?: true
|
livenessKey?: true
|
||||||
bankName?: true
|
bankName?: true
|
||||||
bankAccountNumber?: true
|
bankAccountNumber?: true
|
||||||
bankAccountName?: true
|
bankAccountName?: true
|
||||||
@@ -123,7 +123,7 @@ export type OrganizerVerificationMaxAggregateInputType = {
|
|||||||
birthDate?: true
|
birthDate?: true
|
||||||
address?: true
|
address?: true
|
||||||
ktpImageKey?: true
|
ktpImageKey?: true
|
||||||
selfieKey?: true
|
livenessKey?: true
|
||||||
bankName?: true
|
bankName?: true
|
||||||
bankAccountNumber?: true
|
bankAccountNumber?: true
|
||||||
bankAccountName?: true
|
bankAccountName?: true
|
||||||
@@ -145,7 +145,7 @@ export type OrganizerVerificationCountAggregateInputType = {
|
|||||||
birthDate?: true
|
birthDate?: true
|
||||||
address?: true
|
address?: true
|
||||||
ktpImageKey?: true
|
ktpImageKey?: true
|
||||||
selfieKey?: true
|
livenessKey?: true
|
||||||
bankName?: true
|
bankName?: true
|
||||||
bankAccountNumber?: true
|
bankAccountNumber?: true
|
||||||
bankAccountName?: true
|
bankAccountName?: true
|
||||||
@@ -240,7 +240,7 @@ export type OrganizerVerificationGroupByOutputType = {
|
|||||||
birthDate: Date
|
birthDate: Date
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -283,7 +283,7 @@ export type OrganizerVerificationWhereInput = {
|
|||||||
birthDate?: Prisma.DateTimeFilter<"OrganizerVerification"> | Date | string
|
birthDate?: Prisma.DateTimeFilter<"OrganizerVerification"> | Date | string
|
||||||
address?: Prisma.StringFilter<"OrganizerVerification"> | string
|
address?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
ktpImageKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
ktpImageKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
selfieKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
livenessKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankAccountNumber?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankAccountNumber?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankAccountName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankAccountName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
@@ -307,7 +307,7 @@ export type OrganizerVerificationOrderByWithRelationInput = {
|
|||||||
birthDate?: Prisma.SortOrder
|
birthDate?: Prisma.SortOrder
|
||||||
address?: Prisma.SortOrder
|
address?: Prisma.SortOrder
|
||||||
ktpImageKey?: Prisma.SortOrder
|
ktpImageKey?: Prisma.SortOrder
|
||||||
selfieKey?: Prisma.SortOrder
|
livenessKey?: Prisma.SortOrder
|
||||||
bankName?: Prisma.SortOrder
|
bankName?: Prisma.SortOrder
|
||||||
bankAccountNumber?: Prisma.SortOrder
|
bankAccountNumber?: Prisma.SortOrder
|
||||||
bankAccountName?: Prisma.SortOrder
|
bankAccountName?: Prisma.SortOrder
|
||||||
@@ -334,7 +334,7 @@ export type OrganizerVerificationWhereUniqueInput = Prisma.AtLeast<{
|
|||||||
birthDate?: Prisma.DateTimeFilter<"OrganizerVerification"> | Date | string
|
birthDate?: Prisma.DateTimeFilter<"OrganizerVerification"> | Date | string
|
||||||
address?: Prisma.StringFilter<"OrganizerVerification"> | string
|
address?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
ktpImageKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
ktpImageKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
selfieKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
livenessKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankAccountNumber?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankAccountNumber?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankAccountName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankAccountName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
@@ -358,7 +358,7 @@ export type OrganizerVerificationOrderByWithAggregationInput = {
|
|||||||
birthDate?: Prisma.SortOrder
|
birthDate?: Prisma.SortOrder
|
||||||
address?: Prisma.SortOrder
|
address?: Prisma.SortOrder
|
||||||
ktpImageKey?: Prisma.SortOrder
|
ktpImageKey?: Prisma.SortOrder
|
||||||
selfieKey?: Prisma.SortOrder
|
livenessKey?: Prisma.SortOrder
|
||||||
bankName?: Prisma.SortOrder
|
bankName?: Prisma.SortOrder
|
||||||
bankAccountNumber?: Prisma.SortOrder
|
bankAccountNumber?: Prisma.SortOrder
|
||||||
bankAccountName?: Prisma.SortOrder
|
bankAccountName?: Prisma.SortOrder
|
||||||
@@ -386,7 +386,7 @@ export type OrganizerVerificationScalarWhereWithAggregatesInput = {
|
|||||||
birthDate?: Prisma.DateTimeWithAggregatesFilter<"OrganizerVerification"> | Date | string
|
birthDate?: Prisma.DateTimeWithAggregatesFilter<"OrganizerVerification"> | Date | string
|
||||||
address?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
address?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
||||||
ktpImageKey?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
ktpImageKey?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
||||||
selfieKey?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
livenessKey?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
||||||
bankName?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
bankName?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
||||||
bankAccountNumber?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
bankAccountNumber?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
||||||
bankAccountName?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
bankAccountName?: Prisma.StringWithAggregatesFilter<"OrganizerVerification"> | string
|
||||||
@@ -407,7 +407,7 @@ export type OrganizerVerificationCreateInput = {
|
|||||||
birthDate: Date | string
|
birthDate: Date | string
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -430,7 +430,7 @@ export type OrganizerVerificationUncheckedCreateInput = {
|
|||||||
birthDate: Date | string
|
birthDate: Date | string
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -451,7 +451,7 @@ export type OrganizerVerificationUpdateInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -474,7 +474,7 @@ export type OrganizerVerificationUncheckedUpdateInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -496,7 +496,7 @@ export type OrganizerVerificationCreateManyInput = {
|
|||||||
birthDate: Date | string
|
birthDate: Date | string
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -517,7 +517,7 @@ export type OrganizerVerificationUpdateManyMutationInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -538,7 +538,7 @@ export type OrganizerVerificationUncheckedUpdateManyInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -575,7 +575,7 @@ export type OrganizerVerificationCountOrderByAggregateInput = {
|
|||||||
birthDate?: Prisma.SortOrder
|
birthDate?: Prisma.SortOrder
|
||||||
address?: Prisma.SortOrder
|
address?: Prisma.SortOrder
|
||||||
ktpImageKey?: Prisma.SortOrder
|
ktpImageKey?: Prisma.SortOrder
|
||||||
selfieKey?: Prisma.SortOrder
|
livenessKey?: Prisma.SortOrder
|
||||||
bankName?: Prisma.SortOrder
|
bankName?: Prisma.SortOrder
|
||||||
bankAccountNumber?: Prisma.SortOrder
|
bankAccountNumber?: Prisma.SortOrder
|
||||||
bankAccountName?: Prisma.SortOrder
|
bankAccountName?: Prisma.SortOrder
|
||||||
@@ -597,7 +597,7 @@ export type OrganizerVerificationMaxOrderByAggregateInput = {
|
|||||||
birthDate?: Prisma.SortOrder
|
birthDate?: Prisma.SortOrder
|
||||||
address?: Prisma.SortOrder
|
address?: Prisma.SortOrder
|
||||||
ktpImageKey?: Prisma.SortOrder
|
ktpImageKey?: Prisma.SortOrder
|
||||||
selfieKey?: Prisma.SortOrder
|
livenessKey?: Prisma.SortOrder
|
||||||
bankName?: Prisma.SortOrder
|
bankName?: Prisma.SortOrder
|
||||||
bankAccountNumber?: Prisma.SortOrder
|
bankAccountNumber?: Prisma.SortOrder
|
||||||
bankAccountName?: Prisma.SortOrder
|
bankAccountName?: Prisma.SortOrder
|
||||||
@@ -619,7 +619,7 @@ export type OrganizerVerificationMinOrderByAggregateInput = {
|
|||||||
birthDate?: Prisma.SortOrder
|
birthDate?: Prisma.SortOrder
|
||||||
address?: Prisma.SortOrder
|
address?: Prisma.SortOrder
|
||||||
ktpImageKey?: Prisma.SortOrder
|
ktpImageKey?: Prisma.SortOrder
|
||||||
selfieKey?: Prisma.SortOrder
|
livenessKey?: Prisma.SortOrder
|
||||||
bankName?: Prisma.SortOrder
|
bankName?: Prisma.SortOrder
|
||||||
bankAccountNumber?: Prisma.SortOrder
|
bankAccountNumber?: Prisma.SortOrder
|
||||||
bankAccountName?: Prisma.SortOrder
|
bankAccountName?: Prisma.SortOrder
|
||||||
@@ -718,7 +718,7 @@ export type OrganizerVerificationCreateWithoutUserInput = {
|
|||||||
birthDate: Date | string
|
birthDate: Date | string
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -739,7 +739,7 @@ export type OrganizerVerificationUncheckedCreateWithoutUserInput = {
|
|||||||
birthDate: Date | string
|
birthDate: Date | string
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -765,7 +765,7 @@ export type OrganizerVerificationCreateWithoutReviewedByInput = {
|
|||||||
birthDate: Date | string
|
birthDate: Date | string
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -787,7 +787,7 @@ export type OrganizerVerificationUncheckedCreateWithoutReviewedByInput = {
|
|||||||
birthDate: Date | string
|
birthDate: Date | string
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -828,7 +828,7 @@ export type OrganizerVerificationUpdateWithoutUserInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -849,7 +849,7 @@ export type OrganizerVerificationUncheckedUpdateWithoutUserInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -890,7 +890,7 @@ export type OrganizerVerificationScalarWhereInput = {
|
|||||||
birthDate?: Prisma.DateTimeFilter<"OrganizerVerification"> | Date | string
|
birthDate?: Prisma.DateTimeFilter<"OrganizerVerification"> | Date | string
|
||||||
address?: Prisma.StringFilter<"OrganizerVerification"> | string
|
address?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
ktpImageKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
ktpImageKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
selfieKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
livenessKey?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankAccountNumber?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankAccountNumber?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
bankAccountName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
bankAccountName?: Prisma.StringFilter<"OrganizerVerification"> | string
|
||||||
@@ -912,7 +912,7 @@ export type OrganizerVerificationCreateManyReviewedByInput = {
|
|||||||
birthDate: Date | string
|
birthDate: Date | string
|
||||||
address: string
|
address: string
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -932,7 +932,7 @@ export type OrganizerVerificationUpdateWithoutReviewedByInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -954,7 +954,7 @@ export type OrganizerVerificationUncheckedUpdateWithoutReviewedByInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -975,7 +975,7 @@ export type OrganizerVerificationUncheckedUpdateManyWithoutReviewedByInput = {
|
|||||||
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
birthDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||||
address?: Prisma.StringFieldUpdateOperationsInput | string
|
address?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
ktpImageKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
selfieKey?: Prisma.StringFieldUpdateOperationsInput | string
|
livenessKey?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
bankAccountName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||||
@@ -998,7 +998,7 @@ export type OrganizerVerificationSelect<ExtArgs extends runtime.Types.Extensions
|
|||||||
birthDate?: boolean
|
birthDate?: boolean
|
||||||
address?: boolean
|
address?: boolean
|
||||||
ktpImageKey?: boolean
|
ktpImageKey?: boolean
|
||||||
selfieKey?: boolean
|
livenessKey?: boolean
|
||||||
bankName?: boolean
|
bankName?: boolean
|
||||||
bankAccountNumber?: boolean
|
bankAccountNumber?: boolean
|
||||||
bankAccountName?: boolean
|
bankAccountName?: boolean
|
||||||
@@ -1022,7 +1022,7 @@ export type OrganizerVerificationSelectCreateManyAndReturn<ExtArgs extends runti
|
|||||||
birthDate?: boolean
|
birthDate?: boolean
|
||||||
address?: boolean
|
address?: boolean
|
||||||
ktpImageKey?: boolean
|
ktpImageKey?: boolean
|
||||||
selfieKey?: boolean
|
livenessKey?: boolean
|
||||||
bankName?: boolean
|
bankName?: boolean
|
||||||
bankAccountNumber?: boolean
|
bankAccountNumber?: boolean
|
||||||
bankAccountName?: boolean
|
bankAccountName?: boolean
|
||||||
@@ -1046,7 +1046,7 @@ export type OrganizerVerificationSelectUpdateManyAndReturn<ExtArgs extends runti
|
|||||||
birthDate?: boolean
|
birthDate?: boolean
|
||||||
address?: boolean
|
address?: boolean
|
||||||
ktpImageKey?: boolean
|
ktpImageKey?: boolean
|
||||||
selfieKey?: boolean
|
livenessKey?: boolean
|
||||||
bankName?: boolean
|
bankName?: boolean
|
||||||
bankAccountNumber?: boolean
|
bankAccountNumber?: boolean
|
||||||
bankAccountName?: boolean
|
bankAccountName?: boolean
|
||||||
@@ -1070,7 +1070,7 @@ export type OrganizerVerificationSelectScalar = {
|
|||||||
birthDate?: boolean
|
birthDate?: boolean
|
||||||
address?: boolean
|
address?: boolean
|
||||||
ktpImageKey?: boolean
|
ktpImageKey?: boolean
|
||||||
selfieKey?: boolean
|
livenessKey?: boolean
|
||||||
bankName?: boolean
|
bankName?: boolean
|
||||||
bankAccountNumber?: boolean
|
bankAccountNumber?: boolean
|
||||||
bankAccountName?: boolean
|
bankAccountName?: boolean
|
||||||
@@ -1083,7 +1083,7 @@ export type OrganizerVerificationSelectScalar = {
|
|||||||
updatedAt?: boolean
|
updatedAt?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OrganizerVerificationOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "userId" | "fullName" | "nikEncrypted" | "nikHash" | "birthDate" | "address" | "ktpImageKey" | "selfieKey" | "bankName" | "bankAccountNumber" | "bankAccountName" | "status" | "rejectionReason" | "reviewedAt" | "reviewedById" | "verifiedAt" | "createdAt" | "updatedAt", ExtArgs["result"]["organizerVerification"]>
|
export type OrganizerVerificationOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "userId" | "fullName" | "nikEncrypted" | "nikHash" | "birthDate" | "address" | "ktpImageKey" | "livenessKey" | "bankName" | "bankAccountNumber" | "bankAccountName" | "status" | "rejectionReason" | "reviewedAt" | "reviewedById" | "verifiedAt" | "createdAt" | "updatedAt", ExtArgs["result"]["organizerVerification"]>
|
||||||
export type OrganizerVerificationInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
export type OrganizerVerificationInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||||
reviewedBy?: boolean | Prisma.OrganizerVerification$reviewedByArgs<ExtArgs>
|
reviewedBy?: boolean | Prisma.OrganizerVerification$reviewedByArgs<ExtArgs>
|
||||||
@@ -1125,9 +1125,10 @@ export type $OrganizerVerificationPayload<ExtArgs extends runtime.Types.Extensio
|
|||||||
*/
|
*/
|
||||||
ktpImageKey: string
|
ktpImageKey: string
|
||||||
/**
|
/**
|
||||||
* Storage key selfie memegang KTP.
|
* Storage key foto liveness — user memegang kertas bertuliskan "SETRIP".
|
||||||
|
* (Sebelumnya: selfie memegang KTP. Diganti supaya user tidak perlu memajang KTP dua kali.)
|
||||||
*/
|
*/
|
||||||
selfieKey: string
|
livenessKey: string
|
||||||
bankName: string
|
bankName: string
|
||||||
bankAccountNumber: string
|
bankAccountNumber: string
|
||||||
bankAccountName: string
|
bankAccountName: string
|
||||||
@@ -1571,7 +1572,7 @@ export interface OrganizerVerificationFieldRefs {
|
|||||||
readonly birthDate: Prisma.FieldRef<"OrganizerVerification", 'DateTime'>
|
readonly birthDate: Prisma.FieldRef<"OrganizerVerification", 'DateTime'>
|
||||||
readonly address: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
readonly address: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
||||||
readonly ktpImageKey: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
readonly ktpImageKey: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
||||||
readonly selfieKey: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
readonly livenessKey: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
||||||
readonly bankName: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
readonly bankName: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
||||||
readonly bankAccountNumber: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
readonly bankAccountNumber: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
||||||
readonly bankAccountName: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
readonly bankAccountName: Prisma.FieldRef<"OrganizerVerification", 'String'>
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ export default async function VerifyPage() {
|
|||||||
birthDate: verification.birthDate,
|
birthDate: verification.birthDate,
|
||||||
address: verification.address,
|
address: verification.address,
|
||||||
ktpImageKey: verification.ktpImageKey,
|
ktpImageKey: verification.ktpImageKey,
|
||||||
selfieKey: verification.selfieKey,
|
livenessKey: verification.livenessKey,
|
||||||
bankName: verification.bankName,
|
bankName: verification.bankName,
|
||||||
bankAccountNumber: verification.bankAccountNumber,
|
bankAccountNumber: verification.bankAccountNumber,
|
||||||
bankAccountName: verification.bankAccountName,
|
bankAccountName: verification.bankAccountName,
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ NEXTAUTH_URL="http://localhost:3000"
|
|||||||
NEXT_PUBLIC_SITE_URL="https://arifal.imola.ai"
|
NEXT_PUBLIC_SITE_URL="https://arifal.imola.ai"
|
||||||
ADMIN_EMAILS=admin@setrip.id
|
ADMIN_EMAILS=admin@setrip.id
|
||||||
|
|
||||||
# 32-byte key (hex) for AES-256-GCM encryption of KYC data (NIK + KTP/selfie files)
|
# 32-byte key (hex) for AES-256-GCM encryption of KYC data (NIK + KTP/liveness files)
|
||||||
# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
||||||
KYC_ENCRYPTION_KEY=
|
KYC_ENCRYPTION_KEY=
|
||||||
# 32-byte hex secret used as HMAC pepper for NIK uniqueness lookup
|
# 32-byte hex secret used as HMAC pepper for NIK uniqueness lookup
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export async function submitVerificationAction(formData: FormData) {
|
|||||||
birthDate: formData.get("birthDate") as string,
|
birthDate: formData.get("birthDate") as string,
|
||||||
address: formData.get("address") as string,
|
address: formData.get("address") as string,
|
||||||
ktpImageKey: formData.get("ktpImageKey") as string,
|
ktpImageKey: formData.get("ktpImageKey") as string,
|
||||||
selfieKey: formData.get("selfieKey") as string,
|
livenessKey: formData.get("livenessKey") as string,
|
||||||
bankName: formData.get("bankName") as string,
|
bankName: formData.get("bankName") as string,
|
||||||
bankAccountNumber: formData.get("bankAccountNumber") as string,
|
bankAccountNumber: formData.get("bankAccountNumber") as string,
|
||||||
bankAccountName: formData.get("bankAccountName") as string,
|
bankAccountName: formData.get("bankAccountName") as string,
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ export function ReviewCard({ verification }: { verification: Verification }) {
|
|||||||
src={`/api/files/kyc/${verification.id}/ktp`}
|
src={`/api/files/kyc/${verification.id}/ktp`}
|
||||||
/>
|
/>
|
||||||
<ImagePreview
|
<ImagePreview
|
||||||
label="Selfie + KTP"
|
label="Foto memegang kertas SETRIP"
|
||||||
src={`/api/files/kyc/${verification.id}/selfie`}
|
src={`/api/files/kyc/${verification.id}/liveness`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ type Initial = {
|
|||||||
birthDate: Date;
|
birthDate: Date;
|
||||||
address: string;
|
address: string;
|
||||||
ktpImageKey: string;
|
ktpImageKey: string;
|
||||||
selfieKey: string;
|
livenessKey: string;
|
||||||
bankName: string;
|
bankName: string;
|
||||||
bankAccountNumber: string;
|
bankAccountNumber: string;
|
||||||
bankAccountName: string;
|
bankAccountName: string;
|
||||||
} | null;
|
} | null;
|
||||||
|
|
||||||
type UploadKind = "ktp" | "selfie";
|
type UploadKind = "ktp" | "liveness";
|
||||||
|
|
||||||
const ACCEPT_MIME = "image/jpeg,image/png,image/webp";
|
const ACCEPT_MIME = "image/jpeg,image/png,image/webp";
|
||||||
const MAX_BYTES = 5 * 1024 * 1024;
|
const MAX_BYTES = 5 * 1024 * 1024;
|
||||||
@@ -33,19 +33,19 @@ export function VerifyForm({ initial }: { initial: Initial }) {
|
|||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [ktpKey, setKtpKey] = useState(initial?.ktpImageKey ?? "");
|
const [ktpKey, setKtpKey] = useState(initial?.ktpImageKey ?? "");
|
||||||
const [selfieKey, setSelfieKey] = useState(initial?.selfieKey ?? "");
|
const [livenessKey, setLivenessKey] = useState(initial?.livenessKey ?? "");
|
||||||
|
|
||||||
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
|
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setError("");
|
setError("");
|
||||||
if (!ktpKey || !selfieKey) {
|
if (!ktpKey || !livenessKey) {
|
||||||
setError("Foto KTP dan selfie wajib diunggah");
|
setError("Foto KTP dan foto memegang kertas SETRIP wajib diunggah");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const formData = new FormData(e.currentTarget);
|
const formData = new FormData(e.currentTarget);
|
||||||
formData.set("ktpImageKey", ktpKey);
|
formData.set("ktpImageKey", ktpKey);
|
||||||
formData.set("selfieKey", selfieKey);
|
formData.set("livenessKey", livenessKey);
|
||||||
const result = await submitVerificationAction(formData);
|
const result = await submitVerificationAction(formData);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
@@ -143,13 +143,22 @@ export function VerifyForm({ initial }: { initial: Initial }) {
|
|||||||
onChange={setKtpKey}
|
onChange={setKtpKey}
|
||||||
onError={setError}
|
onError={setError}
|
||||||
/>
|
/>
|
||||||
<FileUpload
|
<div>
|
||||||
label="Selfie dengan KTP"
|
<FileUpload
|
||||||
kind="selfie"
|
label="Foto kamu memegang kertas tulisan SETRIP"
|
||||||
value={selfieKey}
|
kind="liveness"
|
||||||
onChange={setSelfieKey}
|
value={livenessKey}
|
||||||
onError={setError}
|
onChange={setLivenessKey}
|
||||||
/>
|
onError={setError}
|
||||||
|
/>
|
||||||
|
<p className="mt-1.5 text-[11px] leading-relaxed text-neutral-500">
|
||||||
|
Tulis kata <span className="font-semibold">SETRIP</span> dengan
|
||||||
|
tangan di selembar kertas, lalu foto diri kamu sambil memegang
|
||||||
|
kertas itu — pastikan wajah & tulisan terlihat jelas dalam satu
|
||||||
|
foto. Foto ini bukti bahwa pengajuan benar dilakukan oleh kamu
|
||||||
|
sendiri.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,13 @@ export const submitVerificationSchema = z.object({
|
|||||||
.string()
|
.string()
|
||||||
.trim()
|
.trim()
|
||||||
.regex(/^ktp\/[A-Za-z0-9_-]+\.(jpg|png|webp)$/, "Foto KTP wajib diunggah"),
|
.regex(/^ktp\/[A-Za-z0-9_-]+\.(jpg|png|webp)$/, "Foto KTP wajib diunggah"),
|
||||||
selfieKey: z
|
livenessKey: z
|
||||||
.string()
|
.string()
|
||||||
.trim()
|
.trim()
|
||||||
.regex(/^selfie\/[A-Za-z0-9_-]+\.(jpg|png|webp)$/, "Foto selfie wajib diunggah"),
|
.regex(
|
||||||
|
/^liveness\/[A-Za-z0-9_-]+\.(jpg|png|webp)$/,
|
||||||
|
"Foto memegang kertas SETRIP wajib diunggah"
|
||||||
|
),
|
||||||
bankName: z
|
bankName: z
|
||||||
.string()
|
.string()
|
||||||
.trim()
|
.trim()
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import path from "node:path";
|
|||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
import { encryptBuffer, decryptBuffer } from "@/lib/crypto";
|
import { encryptBuffer, decryptBuffer } from "@/lib/crypto";
|
||||||
|
|
||||||
export type KycKind = "ktp" | "selfie";
|
export type KycKind = "ktp" | "liveness";
|
||||||
|
|
||||||
const KIND_DIRS: Record<KycKind, string> = {
|
const KIND_DIRS: Record<KycKind, string> = {
|
||||||
ktp: "ktp",
|
ktp: "ktp",
|
||||||
selfie: "selfie",
|
liveness: "liveness",
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Bytes. ~5MB matches the form limit; raise here if you change the upload route. */
|
/** Bytes. ~5MB matches the form limit; raise here if you change the upload route. */
|
||||||
@@ -43,7 +43,7 @@ export type StoredFileMeta = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function isKycKind(value: string): value is KycKind {
|
export function isKycKind(value: string): value is KycKind {
|
||||||
return value === "ktp" || value === "selfie";
|
return value === "ktp" || value === "liveness";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolve a storage key (`ktp/abc.jpg`) to an absolute path inside the upload dir. Throws on traversal. */
|
/** Resolve a storage key (`ktp/abc.jpg`) to an absolute path inside the upload dir. Throws on traversal. */
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- AlterTable: rename selfieKey -> livenessKey.
|
||||||
|
-- Sebelumnya: storage key untuk selfie memegang KTP.
|
||||||
|
-- Sekarang: storage key foto liveness (user memegang kertas tulisan "SETRIP").
|
||||||
|
ALTER TABLE "OrganizerVerification" RENAME COLUMN "selfieKey" TO "livenessKey";
|
||||||
@@ -99,8 +99,9 @@ model OrganizerVerification {
|
|||||||
|
|
||||||
/// Storage key foto KTP (mis. `ktp/<id>.jpg`). File disimpan terenkripsi di luar /public.
|
/// Storage key foto KTP (mis. `ktp/<id>.jpg`). File disimpan terenkripsi di luar /public.
|
||||||
ktpImageKey String
|
ktpImageKey String
|
||||||
/// Storage key selfie memegang KTP.
|
/// Storage key foto liveness — user memegang kertas bertuliskan "SETRIP".
|
||||||
selfieKey String
|
/// (Sebelumnya: selfie memegang KTP. Diganti supaya user tidak perlu memajang KTP dua kali.)
|
||||||
|
livenessKey String
|
||||||
|
|
||||||
bankName String
|
bankName String
|
||||||
bankAccountNumber String
|
bankAccountNumber String
|
||||||
|
|||||||
+2
-2
@@ -69,7 +69,7 @@ async function main() {
|
|||||||
birthDate: new Date(Date.UTC(1990, 0, 1)),
|
birthDate: new Date(Date.UTC(1990, 0, 1)),
|
||||||
address: "Jl. Pendaki No. 1, Garut, Jawa Barat",
|
address: "Jl. Pendaki No. 1, Garut, Jawa Barat",
|
||||||
ktpImageKey: "ktp/seed-dede.jpg",
|
ktpImageKey: "ktp/seed-dede.jpg",
|
||||||
selfieKey: "selfie/seed-dede.jpg",
|
livenessKey: "liveness/seed-dede.jpg",
|
||||||
bankName: "BCA",
|
bankName: "BCA",
|
||||||
bankAccountNumber: "1234567890",
|
bankAccountNumber: "1234567890",
|
||||||
bankAccountName: "Dede Inoen",
|
bankAccountName: "Dede Inoen",
|
||||||
@@ -85,7 +85,7 @@ async function main() {
|
|||||||
birthDate: new Date(Date.UTC(1985, 5, 15)),
|
birthDate: new Date(Date.UTC(1985, 5, 15)),
|
||||||
address: "Jl. Adventure No. 7, Kuningan, Jawa Barat",
|
address: "Jl. Adventure No. 7, Kuningan, Jawa Barat",
|
||||||
ktpImageKey: "ktp/seed-panji.jpg",
|
ktpImageKey: "ktp/seed-panji.jpg",
|
||||||
selfieKey: "selfie/seed-panji.jpg",
|
livenessKey: "liveness/seed-panji.jpg",
|
||||||
bankName: "Mandiri",
|
bankName: "Mandiri",
|
||||||
bankAccountNumber: "9876543210",
|
bankAccountNumber: "9876543210",
|
||||||
bankAccountName: "Panji Petualang",
|
bankAccountName: "Panji Petualang",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type SubmitInput = {
|
|||||||
birthDate: Date;
|
birthDate: Date;
|
||||||
address: string;
|
address: string;
|
||||||
ktpImageKey: string;
|
ktpImageKey: string;
|
||||||
selfieKey: string;
|
livenessKey: string;
|
||||||
bankName: string;
|
bankName: string;
|
||||||
bankAccountNumber: string;
|
bankAccountNumber: string;
|
||||||
bankAccountName: string;
|
bankAccountName: string;
|
||||||
@@ -36,7 +36,7 @@ export const organizerService = {
|
|||||||
birthDate: data.birthDate,
|
birthDate: data.birthDate,
|
||||||
address: data.address,
|
address: data.address,
|
||||||
ktpImageKey: data.ktpImageKey,
|
ktpImageKey: data.ktpImageKey,
|
||||||
selfieKey: data.selfieKey,
|
livenessKey: data.livenessKey,
|
||||||
bankName: data.bankName,
|
bankName: data.bankName,
|
||||||
bankAccountNumber: data.bankAccountNumber,
|
bankAccountNumber: data.bankAccountNumber,
|
||||||
bankAccountName: data.bankAccountName,
|
bankAccountName: data.bankAccountName,
|
||||||
|
|||||||
Reference in New Issue
Block a user