Skip to content

Membuat api - #5

Closed
migthyhbb wants to merge 5 commits into
mainfrom
membuat-api
Closed

Membuat api#5
migthyhbb wants to merge 5 commits into
mainfrom
membuat-api

Conversation

@migthyhbb

@migthyhbb migthyhbb commented Aug 7, 2026

Copy link
Copy Markdown
Owner

cekk coderabbit

Summary by CodeRabbit

  • New Features

    • Added agent and company registration with validation and rollback protection.
    • Added login, profile retrieval, E-Contract approval, and administrator verification workflows.
    • Added pending partner management and role-based dashboard access controls.
    • Added authentication redirects based on account roles.
  • Bug Fixes

    • Improved authentication, authorization, validation, rate limiting, and error handling across account workflows.
  • Chores

    • Removed the connection test endpoint and legacy client setup.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2419ccfe-3289-440b-81be-480bbc6d5f2a

📥 Commits

Reviewing files that changed from the base of the PR and between 8ba4627 and d9e12c2.

📒 Files selected for processing (3)
  • app/api/admin/verifikasi/route.ts
  • app/api/profil/me/route.ts
  • app/api/registrasi_agen/route.ts

📝 Walkthrough

Walkthrough

Added server-side Supabase authentication, role-based middleware, partner registration, profile access, login, verification, and E-Contract API routes. Removed the legacy Supabase client and connection-test route.

Changes

Supabase authentication and partner workflows

Layer / File(s) Summary
Server authentication foundation
lib/supabase/server.ts, middleware.ts, package.json
Added server and admin Supabase clients, cookie synchronization, role-based redirects, route matching, and Supabase SSR dependencies.
Partner registration and rollback
app/api/registrasi_agen/route.ts, app/api/registrasi_perusahaan/route.ts
Added agent and company registration. Each route creates an Auth user, assigns role metadata, inserts a profile, and rolls back the Auth user when profile setup fails.
Login and profile access
app/api/auth/login/route.ts, app/api/profil/me/route.ts
Added validated login handling and role-based profile retrieval for authenticated users.
Agent contract approval
app/api/legal/e-contract/route.ts
Added an agent-only endpoint that records approval time and updates the agent verification status.
Admin partner review
app/api/admin/calon-mitra/route.ts, app/api/admin/verifikasi/route.ts
Added pending-partner listing and admin verification updates for agent and company records.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant RegistrationRoute
  participant SupabaseAuth
  participant AdminClient
  Client->>RegistrationRoute: submit registration data
  RegistrationRoute->>SupabaseAuth: create Auth user
  SupabaseAuth-->>RegistrationRoute: return user id
  RegistrationRoute->>AdminClient: assign role and insert profile
  AdminClient-->>RegistrationRoute: return operation result
  RegistrationRoute-->>Client: return success or error response
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title describes the main change, which adds multiple API routes and supporting authentication infrastructure, but it is broad.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch membuat-api

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (3)
lib/supabase/server.ts (2)

5-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Read the admin credentials inside createAdminClient instead of accepting them as parameters.

createAdminClient requires callers to pass the service-role key. Both registration routes bypass this helper and call createClient from @supabase/supabase-js directly with process.env.SUPABASE_SERVICE_ROLE_KEY!. The non-null assertion hides a missing key until requests fail at runtime. Move the env read and validation into this factory, then use it in the registration routes.

♻️ Proposed refactor
-export function createAdminClient(url: string, key: string) {
-  return createSupabaseAdmin(url, key, {
+export function createAdminClient() {
+  const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
+  const key = process.env.SUPABASE_SERVICE_ROLE_KEY;
+  if (!url || !key) {
+    throw new Error('Supabase admin environment variables are missing!');
+  }
+  return createSupabaseAdmin(url, key, {
     auth: {
       autoRefreshToken: false,
       persistSession: false,
     },
   });
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/supabase/server.ts` around lines 5 - 12, Update createAdminClient to read
the Supabase URL and service-role key from environment configuration, validate
that the required key exists, and stop accepting credentials as parameters.
Replace the direct createClient calls in both registration routes with
createAdminClient so all admin clients use the centralized validated
configuration.

25-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Migrate the cookie adapter to getAll/setAll.

@supabase/ssr 0.12.4 deprecates get, set, and remove. Use getAll and setAll to support chunked session cookies and match middleware.ts. Keep one documented catch for the Server Component cookie-write restriction. Remove the unused CookieOptions import.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/supabase/server.ts` around lines 25 - 44, The cookie adapter around the
cookies object must migrate from get/set/remove to getAll/setAll, matching the
middleware adapter and supporting chunked session cookies. Replace the
individual cookie operations with the corresponding bulk methods, retain one
documented catch for the Server Component cookie-write restriction, and remove
the now-unused CookieOptions import.
app/api/registrasi_agen/route.ts (1)

5-24: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Validate the field formats, not only their presence.

The check rejects empty values only. email, nikNib, and noTelepon reach Supabase and the database without format checks, and password has no length rule. Non-string values also pass, because only falsiness is tested. Consider a schema validator such as zod, which the two registration routes can share.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/registrasi_agen/route.ts` around lines 5 - 24, Enhance validation in
the POST handler using a shared schema for both registration routes, such as
Zod. Validate that all fields are strings, enforce proper email formatting,
apply the expected NIK/NIB and phone-number formats, and require a minimum
password length before contacting Supabase; return the existing 400-style
validation response for schema failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/api/admin/verifikasi/route.ts`:
- Around line 44-52: Validate that the parsed body in the request handler is a
non-null object before destructuring id_target, tipe, and status_baru. Return
the existing 400 invalid-body response for null or other non-object JSON values,
while preserving the current handling for valid object bodies.

In `@app/api/auth/login/route.ts`:
- Around line 55-66: Update the role lookup in the login route to read
data.user?.app_metadata?.role instead of user_metadata, while preserving the
existing response shape and redirect behavior.

In `@app/api/legal/e-contract/route.ts`:
- Around line 23-37: Update the Supabase update flow in the e-contract route to
request the modified agen row and verify that exactly one row was returned for
user.id. Treat zero or multiple matches as an error instead of returning the
success response, while preserving the existing update fields and success
payload for exactly one updated row.

In `@app/api/profil/me/route.ts`:
- Around line 20-39: Update both profile lookups in the role branches of the GET
handler to map Supabase’s PGRST116 “no rows” error to HTTP 404, while preserving
other errors for server-side handling. In the catch block, replace the explicit
any type with a safe error type and return a generic client-facing message
instead of err.message, avoiding exposure of PostgREST or schema details.

In `@app/api/registrasi_agen/route.ts`:
- Around line 29-37: Update the registration flow around the signUp call to stop
placing the role in options.data/user_metadata. Reuse the shared
createAdminClient from `@/lib/supabase/server`, create it before the profile
insert, and use it after signUp to set the new user’s app_metadata.role to agen
so middleware authorization reads the trusted value.
- Around line 69-77: Update the rollback block after the profile creation
failure to capture and inspect the result of
supabaseAdmin.auth.admin.deleteUser(userId), log any deletion failure, and
preserve the rollback failure handling. Replace the client-facing
profileError.message with a generic error response while retaining detailed
error information only in server-side logs.

In `@app/api/registrasi_perusahaan/route.ts`:
- Around line 18-23: Update the validation error returned by the required-field
check to name all six validated fields, including alamatKantor and noTelepon,
while preserving the existing 400 response and condition.

In `@middleware.ts`:
- Around line 32-33: Ensure registration populates app_metadata.role before
authorization by assigning the submitted role through
supabaseAdmin.auth.admin.updateUserById or an equivalent server-side hook.
Update the registration flow and the role checks in login, profil/me, and
e-contract handlers to consistently read app_metadata.role, including replacing
the user-editable metadata access in the e-contract authorization check.

---

Nitpick comments:
In `@app/api/registrasi_agen/route.ts`:
- Around line 5-24: Enhance validation in the POST handler using a shared schema
for both registration routes, such as Zod. Validate that all fields are strings,
enforce proper email formatting, apply the expected NIK/NIB and phone-number
formats, and require a minimum password length before contacting Supabase;
return the existing 400-style validation response for schema failures.

In `@lib/supabase/server.ts`:
- Around line 5-12: Update createAdminClient to read the Supabase URL and
service-role key from environment configuration, validate that the required key
exists, and stop accepting credentials as parameters. Replace the direct
createClient calls in both registration routes with createAdminClient so all
admin clients use the centralized validated configuration.
- Around line 25-44: The cookie adapter around the cookies object must migrate
from get/set/remove to getAll/setAll, matching the middleware adapter and
supporting chunked session cookies. Replace the individual cookie operations
with the corresponding bulk methods, retain one documented catch for the Server
Component cookie-write restriction, and remove the now-unused CookieOptions
import.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8c874d3e-856d-482c-97d6-e1398ba3a020

📥 Commits

Reviewing files that changed from the base of the PR and between 45c84a3 and 3a1abae.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (12)
  • app/api/admin/calon-mitra/route.ts
  • app/api/admin/verifikasi/route.ts
  • app/api/auth/login/route.ts
  • app/api/legal/e-contract/route.ts
  • app/api/profil/me/route.ts
  • app/api/registrasi_agen/route.ts
  • app/api/registrasi_perusahaan/route.ts
  • app/api/test-koneksi/route.ts
  • lib/supabase.ts
  • lib/supabase/server.ts
  • middleware.ts
  • package.json
💤 Files with no reviewable changes (2)
  • lib/supabase.ts
  • app/api/test-koneksi/route.ts

Comment thread app/api/admin/verifikasi/route.ts Outdated
Comment thread app/api/auth/login/route.ts
Comment on lines +23 to +37
// 4. Update tabel 'agen', ubah syarat_disetujui menjadi true
const { error: updateError } = await supabase
.from('agen')
.update({
syarat_disetujui: true,
waktu_persetujuan: waktuSekarang
})
.eq('auth_id', user.id);

if (updateError) throw updateError;

return NextResponse.json({
message: 'E-Contract berhasil disetujui secara digital!',
waktu_persetujuan: waktuSekarang
}, { status: 200 });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win

Critical: the route reports success when no agent row matches.

A Supabase update that matches zero rows returns no error. If the agen row is missing, or if RLS filters it out, updateError stays null and the response states that the E-Contract is approved. No consent is recorded. This endpoint records a legal agreement, so the false confirmation is severe. Request the updated rows and verify that exactly one row changed.

🐛 Proposed fix
-    const { error: updateError } = await supabase
+    const { data: updated, error: updateError } = await supabase
       .from('agen')
       .update({
         syarat_disetujui: true,
         waktu_persetujuan: waktuSekarang
       })
-      .eq('auth_id', user.id);
+      .eq('auth_id', user.id)
+      .select('auth_id');
 
     if (updateError) throw updateError;
+
+    if (!updated || updated.length === 0) {
+      return NextResponse.json(
+        { error: 'Data agen tidak ditemukan' },
+        { status: 404 }
+      );
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/legal/e-contract/route.ts` around lines 23 - 37, Update the Supabase
update flow in the e-contract route to request the modified agen row and verify
that exactly one row was returned for user.id. Treat zero or multiple matches as
an error instead of returning the success response, while preserving the
existing update fields and success payload for exactly one updated row.

Comment on lines +20 to +39
// 3. Tarik data dari tabel yang sesuai menggunakan .single() karena data pasti unik
if (role === 'agen') {
const { data, error } = await supabase
.from('agen')
.select('*')
.eq('auth_id', user.id)
.single();

if (error) throw error;
profileData = data;

} else if (role === 'perusahaan') {
const { data, error } = await supabase
.from('perusahaan_industri')
.select('*')
.eq('auth_id', user.id)
.single();

if (error) throw error;
profileData = data;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Return 404 for a missing profile, and stop returning the raw error message.

.single() returns a PGRST116 error when no row matches. A registered user without a profile row therefore receives HTTP 500. Map that case to 404. The catch block also sends err.message to the client, which exposes Postgrest and schema details. The any type on line 52 fails ESLint @typescript-eslint/no-explicit-any.

🛡️ Proposed fix
     if (role === 'agen') {
       const { data, error } = await supabase
         .from('agen')
         .select('*')
         .eq('auth_id', user.id)
-        .single();
-      
-      if (error) throw error;
+        .maybeSingle();
+
+      if (error) throw error;
+      if (!data) {
+        return NextResponse.json({ error: 'Profil belum tersedia' }, { status: 404 });
+      }
       profileData = data;

Apply the same change to the perusahaan_industri branch, then:

-  } catch (err: any) {
-    return NextResponse.json(
-      { error: 'Terjadi kesalahan server: ' + err.message },
-      { status: 500 }
-    );
+  } catch (err: unknown) {
+    const message = err instanceof Error ? err.message : 'Unknown server error';
+    console.error('Profil error:', message);
+    return NextResponse.json(
+      { error: 'Terjadi kesalahan server' },
+      { status: 500 }
+    );
   }

Also applies to: 52-57

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/profil/me/route.ts` around lines 20 - 39, Update both profile lookups
in the role branches of the GET handler to map Supabase’s PGRST116 “no rows”
error to HTTP 404, while preserving other errors for server-side handling. In
the catch block, replace the explicit any type with a safe error type and return
a generic client-facing message instead of err.message, avoiding exposure of
PostgREST or schema details.

Source: Linters/SAST tools

Comment thread app/api/registrasi_agen/route.ts Outdated
Comment thread app/api/registrasi_agen/route.ts Outdated
Comment thread app/api/registrasi_perusahaan/route.ts
Comment thread middleware.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
lib/supabase/server.ts (1)

9-10: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add explicit Supabase environment checks.

@supabase/ssr already rejects missing values, but explicit checks provide a clearer configuration error. Apply the same check in lib/supabase/server.ts and middleware.ts, consistent with createAdminClient().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/supabase/server.ts` around lines 9 - 10, Add explicit presence checks for
NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY before constructing
the Supabase client in the server setup, matching the validation used by
createAdminClient(). Apply the same validation in middleware.ts and raise the
established clear configuration error when either variable is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/api/profil/me/route.ts`:
- Around line 21-40: Update the role lookup in the profile route to read the
trusted user.app_metadata?.role value instead of user_metadata.role. Preserve
the existing agen and perusahaan_industri profile branches and their response
behavior.

In `@app/api/registrasi_agen/route.ts`:
- Around line 53-57: Update the agen insertion in the registration handler
before the HTTP 201 response: replace the empty insert payload with one object
keyed by the actual table columns, including auth_id: userId, mappings for
namaAgen, nikNib, alamatLengkap, and noTelepon, plus required defaults such as
status_verifikasi: 'pending'. Preserve the existing profileError handling.

---

Nitpick comments:
In `@lib/supabase/server.ts`:
- Around line 9-10: Add explicit presence checks for NEXT_PUBLIC_SUPABASE_URL
and NEXT_PUBLIC_SUPABASE_ANON_KEY before constructing the Supabase client in the
server setup, matching the validation used by createAdminClient(). Apply the
same validation in middleware.ts and raise the established clear configuration
error when either variable is missing.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8eac49dc-008d-4934-a9e2-2ac6d65a803e

📥 Commits

Reviewing files that changed from the base of the PR and between 3a1abae and 8ba4627.

📒 Files selected for processing (6)
  • app/api/admin/verifikasi/route.ts
  • app/api/auth/login/route.ts
  • app/api/profil/me/route.ts
  • app/api/registrasi_agen/route.ts
  • app/api/registrasi_perusahaan/route.ts
  • lib/supabase/server.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/api/registrasi_perusahaan/route.ts
  • app/api/admin/verifikasi/route.ts
  • app/api/auth/login/route.ts

Comment thread app/api/profil/me/route.ts
Comment thread app/api/registrasi_agen/route.ts
@migthyhbb migthyhbb closed this Aug 7, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant