Backend service untuk manajemen data vendor dalam proses pengadaan (procurement), dilengkapi autentikasi berbasis JWT dan otorisasi berbasis role (RBAC).
- Java 17+
- Spring Boot (Web, Security, Data JPA, Validation)
- Spring Security + JWT (jjwt)
- Lombok
- Relational Database (JPA/Hibernate)
- Autentikasi (signup & signin) dengan JWT
- Role-Based Access Control:
ROLE_STAFF,ROLE_FINANCE_MANAGER,ROLE_DIRECTOR,ROLE_ADMIN - Manajemen data vendor (CRUD)
- Lifecycle status vendor dengan validasi transisi state:
DRAFT,IN_REVIEW,ACTIVE,INACTIVE,RETURNED
Alur request dari client hingga masuk ke database, melalui filter JWT dan pengecekan otorisasi.
sequenceDiagram
participant Client
participant AuthTokenFilter
participant SecurityContext
participant Controller
participant Service
participant Repository
participant DB as Database
Client->>AuthTokenFilter: HTTP Request + Bearer Token
AuthTokenFilter->>AuthTokenFilter: parseJwt()
AuthTokenFilter->>AuthTokenFilter: validateJwtToken()
alt Token valid
AuthTokenFilter->>SecurityContext: set Authentication (UserDetails + Authorities)
else Token invalid / tidak ada
AuthTokenFilter->>AuthTokenFilter: skip set authentication
end
AuthTokenFilter->>Controller: forward request
Controller->>Controller: @PreAuthorize check role
alt Role diizinkan
Controller->>Service: panggil business logic
Service->>Repository: query / save data
Repository->>DB: SQL execution
DB-->>Repository: hasil data
Repository-->>Service: entity
Service-->>Controller: response DTO
Controller-->>Client: 200 OK + body
else Role ditolak
Controller-->>Client: 403 Forbidden
end
erDiagram
USERS ||--o{ USER_ROLE : has
ROLES ||--o{ USER_ROLE : assigned_to
VENDORS {
string id PK
string name
string address
string phone UK
string email
string accountNumber
string npwp
string status
string rejectionDescription
}
USERS {
string id PK
string username UK
string email UK
string password
}
ROLES {
int id PK
string roleName UK
}
USER_ROLE {
string user_id FK
int role_id FK
}
Catatan:
USERSdanROLESberelasi many-to-many melalui junction tableUSER_ROLE.VENDORSberdiri independen, status dikontrol lewat enumEVendor.
Fungsi inti aplikasi ada di VendorServiceImpl.updateStatus(), yang memvalidasi transisi status vendor sebelum disimpan.
stateDiagram-v2
[*] --> DRAFT : create()
DRAFT --> IN_REVIEW : submit\n(hanya dari DRAFT)
IN_REVIEW --> ACTIVE : approve\n(hanya dari IN_REVIEW)
IN_REVIEW --> RETURNED : reject\n(hanya dari IN_REVIEW,\nreason wajib diisi)
ACTIVE --> INACTIVE : deactivate\n(reason opsional)
INACTIVE --> DRAFT : reactivate\n(hanya dari INACTIVE/RETURNED)
RETURNED --> DRAFT : reactivate\n(hanya dari INACTIVE/RETURNED)
DRAFT --> [*]
Aturan transisi (divalidasi di service layer, melempar IllegalStateException jika dilanggar):
| Target Status | Syarat Status Sebelumnya | Efek Tambahan |
|---|---|---|
DRAFT |
INACTIVE, RETURNED, atau DRAFT |
- |
IN_REVIEW |
DRAFT |
rejectionDescription direset ke null |
ACTIVE |
IN_REVIEW |
rejectionDescription direset ke null |
RETURNED |
IN_REVIEW |
rejectionDescription diisi alasan |
INACTIVE |
bebas | rejectionDescription diisi alasan |
| Method | Endpoint | Akses | Deskripsi |
|---|---|---|---|
| POST | /api/auth/signup |
Public | Registrasi user baru |
| POST | /api/auth/signin |
Public | Login, menghasilkan JWT |
| Method | Endpoint | Role Diizinkan | Deskripsi |
|---|---|---|---|
| POST | /api/vendors |
ADMIN, FINANCE_MANAGER |
Membuat vendor baru (status: DRAFT) |
| GET | /api/vendors |
ADMIN, FINANCE_MANAGER, DIRECTOR, STAFF |
List vendor (filter by status, default ACTIVE) |
| GET | /api/vendors/{id} |
ADMIN, FINANCE_MANAGER, DIRECTOR, STAFF |
Detail vendor by id |
| PUT | /api/vendors/{id} |
ADMIN, FINANCE_MANAGER |
Update data vendor (status: DRAFT) |
| POST | /api/vendors/{id}/submit |
ADMIN, FINANCE_MANAGER |
Submit vendor untuk direview (DRAFT -> IN_REVIEW) |
| POST | /api/vendors/{id}/approve |
DIRECTOR |
Approve vendor (IN_REVIEW -> ACTIVE) |
| POST | /api/vendors/{id}/reject |
DIRECTOR |
Reject vendor (IN_REVIEW -> RETURNED) |
| POST | /api/vendors/{id}/deactivate |
ADMIN, STAFF, FINANCE_MANAGER |
Nonaktifkan vendor (-> INACTIVE) |
| POST | /api/vendors/{id}/activate |
ADMIN, STAFF, FINANCE_MANAGER |
Kembalikan vendor ke DRAFT untuk diproses ulang |
- Autentikasi stateless menggunakan JWT (
Authorization: Bearer <token>). AuthTokenFiltermemvalidasi token pada setiap request sebelum mencapai controller.- Otorisasi endpoint diatur per-method menggunakan
@PreAuthorizedenganEnableMethodSecurity. - Password di-hash menggunakan
BCryptPasswordEncoder. - Endpoint publik:
/api/auth/**dan/api/health/**; selain itu wajib autentikasi.