27 KiB
Database Reference
Format:
table_name→model_name| columns | relationships
Auth & User
users → User
id email(unique) username(unique) password is_active(bool) last_login_at(datetime) created_at updated_at deleted_at
- Casts: email_verified_at(datetime), is_active(bool), last_login_at(datetime), password(hashed), two_factor_confirmed_at(datetime)
- Implements: HasMedia (Spatie Media Library)
- Media Collections: photos (single photo, with thumb conversion)
- Scopes: active()
- Relations: userProfile(HasOne→UserProfile), employee(HasOne→Employee), attendances(HasMany→Attendance), cashAccounts(HasMany→CashAccount,created_by_id), cashTransactions(HasMany→CashTransaction,created_by_id), createdCuttings(HasMany→Cutting,created_by_id), createdExpenses(HasMany→Expense,created_by_id), createdOrders(HasMany→Order,created_by_id), marketingOrders(HasMany→Order,marketing_id), orderItems(HasMany→OrderItem), createdPurchases(HasMany→Purchase,created_by_id), createdRestocks(HasMany→Restock,created_by_id), stokOpnamesCreated(HasMany→StokOpname,created_by_id), stokOpnamesVerified(HasMany→StokOpname,verified_by_id), employeeAdvancesPaid(HasMany→EmployeeAdvance,paid_by_id), employeeAdvancesVerified(HasMany→EmployeeAdvance,verified_by_id), paidPayrolls(HasMany→Payroll,paid_by_id), payrollPeriodsClosed(HasMany→PayrollPeriod,closed_by_id), notifications(HasMany→AppNotification), rejections(HasMany→Rejection,rejected_by_id), pushSubscriptions(HasMany→PushSubscription,morph)
- Accessor: avatar → temporary S3 URL dari media 'photos' (atau null)
user_profiles → UserProfile
id user_id(FK→users,unique) full_name(200) phone_number(20,null) gender(enum,null) birth_date(date,null) address(text,null) created_at updated_at deleted_at
- Casts: gender(Gender), birth_date(date:Y-m-d)
- Scopes: female(), male(), hasPhoneNumber()
- Relations: user(BelongsTo→User)
push_subscriptions → PushSubscription
id subscribable_type subscribable_id endpoint(500,unique) public_key(null) auth_token(null) content_encoding(null) created_at updated_at
- Relations: user(MorphTo)
notifications → AppNotification
id user_id(FK→users) title body(text,null) url(null) is_read(bool,default:false) read_at(datetime,null) created_at updated_at
- Casts: is_read(bool), read_at(datetime)
- Accessor: formatted_read_at → 'l, d F Y H:i'
- Relations: user(BelongsTo→User)
Master Data
categories → Category
id name(50) slug(50,unique) created_at updated_at deleted_at
- Relations: products(BelongsToMany→Product via product_categories)
- Accessor: formattedName → ucfirst(name)
product_categories → Category (Pivot)
product_id(FK→products) category_id(FK→categories)
- No id, no timestamps
- Relations: category(BelongsTo→Category), product(BelongsTo→Product)
products → Product
id name(200) slug(200,unique) description(text,null) status(enum,default:active) rejection_reason(text,null) created_at updated_at deleted_at
- Casts: status(ProductStatus)
- Scopes: active(), draft(), inactive(), pending(), rejected()
- Relations: categories(BelongsToMany→Category), productVariants(HasMany→ProductVariant)
product_variants → ProductVariant
id product_id(FK→products) name(200) stock(uint,default:0) reject_stock(uint,default:0) retail_stock(uint,default:0) created_at updated_at deleted_at
- Casts: stock(int), reject_stock(int), retail_stock(int)
- GlobalScope: orderBy(name)
- Relations: product(BelongsTo→Product), productPrices(HasMany→ProductPrice,variant_id), orderItems(HasMany→OrderItem), restockItems(HasMany→RestockItem), retailStockHistories(HasMany→RetailStockHistory), stokOpnameItems(HasMany→StokOpnameItem), stockMutations(HasMany→StockMutation,morph)
product_prices → ProductPrice
id variant_id(FK→product_variants) type(enum) price(uint) created_at updated_at
- UNIQUE(variant_id, type)
- Casts: type(PriceType), price(int)
- Scopes: retail(), wholesale()
- Relations: variant(BelongsTo→ProductVariant)
customers → Customer
id name(200) phone_number(20,null) address(text,null) created_at updated_at deleted_at
- Relations: orders(HasMany→Order)
- Accessor: formattedPhoneNumber (get: "0821 2121 2121", set: strip whitespace)
suppliers → Supplier
id name(200) phone_number(20,null) address(text,null) created_at updated_at deleted_at
- Relations: purchases(HasMany→Purchase)
- Accessor: formattedPhoneNumber (get: "0821 2121 2121", set: strip whitespace)
raw_materials → RawMaterial
id name(200) unit(enum) is_active(bool,default:true) created_at updated_at deleted_at
- Casts: unit(RawMaterialUnit), is_active(bool)
- Scopes: active(), nonactive(), kg(), meter(), yard()
- Relations: rawMaterialPrices(HasMany→RawMaterialPrice)
raw_material_prices → RawMaterialPrice
id raw_material_id(FK→raw_materials) variant(200) price(uint) stock(uint,default:0) created_at updated_at deleted_at
- Casts: price(int), stock(int)
- GlobalScope: orderBy(variant)
- Relations: rawMaterial(BelongsTo→RawMaterial,withTrashed), cuttingMaterials(HasMany→CuttingMaterial), purchaseItems(HasMany→PurchaseItem)
- Accessor: photo_url → first media presigned S3 URL
Finance
cash_accounts → CashAccount
id created_by_id(FK→users) name(200) balance(ubig,default:0) created_at updated_at deleted_at
- Casts: balance(int)
- Relations: cashTransactions(HasMany→CashTransaction), createdBy(BelongsTo→User)
cash_transactions → CashTransaction
id cash_account_id(FK→cash_accounts) created_by_id(FK→users) reference_id(ubig,null,morph) reference_type(string,null,morph) amount(ubig) balance_after(ubig) type(enum,default:deposit) description(100) created_at updated_at deleted_at
- Casts: type(CashTransactionType), amount(int), balance_after(int)
- Scopes: deposit(), expenseType(), transfer(), withdrawal()
- Relations: cashAccount(BelongsTo→CashAccount), createdBy(BelongsTo→User), reference(MorphTo), expense(HasOne→Expense), order(HasOne→Order), employeeAdvances(HasMany→EmployeeAdvance), payrolls(HasMany→Payroll)
expenses → Expense
id cash_transaction_id(FK→cash_transactions,unique,null) created_by_id(FK→users) amount(ubig) description(100) created_at updated_at deleted_at
- Casts: amount(int), date(date:Y-m-d)
- Relations: cashTransaction(BelongsTo→CashTransaction), createdBy(BelongsTo→User)
employee_advances → EmployeeAdvance
id paid_by_id(FK→users,null) employee_id(FK→employees) verified_by_id(FK→users,null) repayment_cash_transaction_id(FK→cash_transactions,unique,null) cash_transaction_id(FK→cash_transactions,unique,null) amount(ubig) paid_amount(ubig,default:0) description(100) due_date(date) status(enum,default:pending) verified_at(datetime,null) paid_at(datetime,null) created_at updated_at deleted_at
- Casts: status(EmployeeAdvanceStatus), amount(int), paid_amount(int), due_date(date:Y-m-d), verified_at(datetime), paid_at(datetime)
- Scopes: approved(), cancelled(), paid(), pending(), rejected()
- Relations: employee(BelongsTo→Employee), cashTransaction(BelongsTo→CashTransaction), repaymentCashTransaction(BelongsTo→CashTransaction), paidBy(BelongsTo→User), verifiedBy(BelongsTo→User), payments(HasMany→EmployeeAdvancePayment)
employee_advance_payments → EmployeeAdvancePayment
id employee_advance_id(FK→employee_advances) paid_by_id(FK→users,null) cash_transaction_id(FK→cash_transactions,unique,null) amount(ubig) description(100,null) paid_at(datetime) created_at updated_at
- No soft deletes
- Casts: amount(int), paid_at(datetime)
- Accessor: formatted_amount → 'Rp X.XXX', formatted_paid_at → 'l, d F Y H:i'
- Relations: employeeAdvance(BelongsTo→EmployeeAdvance), paidBy(BelongsTo→User), cashTransaction(BelongsTo→CashTransaction)
HR
employees → Employee
id user_id(FK→users,unique) join_date(date) resign_date(date,null) employment_status(enum,default:full_time) base_salary(uint) created_at updated_at deleted_at
- Casts: employment_status(EmploymentStatus), base_salary(int), join_date(date:Y-m-d), resign_date(date:Y-m-d)
- Scopes: contract(), fullTime(), internship(), partTime(), resigned()
- Relations: user(BelongsTo→User), attendances(HasMany→Attendance), employeeAdvances(HasMany→EmployeeAdvance), leaveRequests(HasMany→LeaveRequest), payrolls(HasMany→Payroll)
attendances → Attendance
id employee_id(FK→employees) attendance_date(date) check_in_at(datetime) check_out_at(datetime,null) check_in_latitude(decimal(10,7),null) check_in_longitude(decimal(10,7),null) check_out_latitude(decimal(10,7),null) check_out_longitude(decimal(10,7),null) work_duration_minutes(uint,null) created_at updated_at
- No soft deletes
- Casts: attendance_date(date:Y-m-d), check_in_at(datetime), check_out_at(datetime), check_in/out_latitude/longitude(decimal:7), work_duration_minutes(int)
- Accessor: formatted_attendance_date → 'l, d F Y', formatted_check_in_at → 'l, d F Y H:i', formatted_check_out_at → 'l, d F Y H:i'
- Relations: employee(BelongsTo→Employee), payrollAdjustments(HasMany→PayrollAdjustment)
payroll_periods → PayrollPeriod
id closed_by_id(FK→users,null) year(usmall) month(utiny) status(enum,default:open) closed_at(datetime,null) created_at updated_at deleted_at
- Casts: status(PayrollPeriodStatus), year(int), month(int), closed_at(datetime)
- Accessor: formatted_closed_at → 'l, d F Y H:i', month_name → 'Januari', status_label
- Scopes: closed(), open()
- Relations: closedBy(BelongsTo→User), payrolls(HasMany→Payroll)
payrolls → Payroll
id payroll_period_id(FK→payroll_periods) employee_id(FK→employees) cash_transaction_id(FK→cash_transactions,unique,null) paid_by_id(FK→users,null) base_salary(uint) bonus_amount(ubig,default:0) deduction_amount(ubig,default:0) total_amount(ubig) status(enum,default:unpaid) paid_at(datetime,null) created_at updated_at deleted_at
- Casts: status(PayrollStatus), base_salary(int), bonus_amount(int), deduction_amount(int), total_amount(int), paid_at(datetime)
- Scopes: cancelled(), paid(), unpaid()
- Relations: payrollPeriod(BelongsTo→PayrollPeriod), employee(BelongsTo→Employee), cashTransaction(BelongsTo→CashTransaction), paidBy(BelongsTo→User), payrollAdjustments(HasMany→PayrollAdjustment)
payroll_adjustments → PayrollAdjustment
id payroll_id(FK→payrolls) attendance_id(FK→attendances,null) created_by_id(FK→users) type(enum) amount(ubig) description(100) created_at updated_at deleted_at
- Casts: type(PayrollAdjustmentType), amount(int)
- Scopes: bonus(), deduction()
- Relations: payroll(BelongsTo→Payroll), attendance(BelongsTo→Attendance), createdBy(BelongsTo→User)
leave_requests → LeaveRequest
id employee_id(FK→employees) verified_by_id(FK→users,null) start_date(date) end_date(date) total_days(uint) status(enum,default:pending) verified_at(datetime,null) created_at updated_at deleted_at
- Casts: status(LeaveRequestStatus), start_date(date:Y-m-d), end_date(date:Y-m-d), total_days(int), verified_at(datetime)
- Scopes: approved(), cancelled(), pending(), rejected()
- Relations: employee(BelongsTo→Employee), verifiedBy(BelongsTo→User)
Sales
orders → Order
id customer_id(FK→customers,null) marketing_id(FK→users,null) cash_transaction_id(FK→cash_transactions,unique,null) created_by_id(FK→users) order_number(30,unique) channel(enum) price_type(enum) status(enum,default:pending) payment_type(enum,default:cash) is_affiliate(bool,default:false) tiktok_order_id(100,null) shopee_order_id(100,null) subtotal(ubig) discount(ubig,default:0) nego_price(ubig,null) marketplace_settings_snapshot(json,null) total_amount(ubig) cogs(ubig,default:0) notes(text,null) created_at updated_at deleted_at
- Casts: channel(OrderChannel), price_type(PriceType), status(OrderStatus), payment_type(PaymentType), is_affiliate(bool), subtotal(int), discount(int), nego_price(int), total_amount(int), cogs(int), marketplace_settings_snapshot(array)
- Scopes: cancelled(), cash(), completed(), pending(), processing(), qris(), refunded(), retail(), shopee(), store(), tiktok(), transfer(), wholesale()
- Relations: cashTransaction(BelongsTo→CashTransaction), createdBy(BelongsTo→User), customer(BelongsTo→Customer), marketing(BelongsTo→User), orderItems(HasMany→OrderItem)
order_items → OrderItem
id order_id(FK→orders,null) user_id(FK→users,null) product_variant_id(FK→product_variants) stock_quality(enum,default:good) quantity(uint) unit_price(ubig) subtotal(ubig) created_at updated_at deleted_at
- Casts: stock_quality(ProductStockQuality), quantity(int), unit_price(int), subtotal(int)
- Scopes: good(), reject()
- Relations: order(BelongsTo→Order), productVariant(BelongsTo→ProductVariant), user(BelongsTo→User)
rejections → Rejection
id rejectable_type(string,null,morph) rejectable_id(ubig,null,morph) rejected_by_id(FK→users) reason(500) created_at updated_at deleted_at
- Relations: rejectable(MorphTo), rejectedBy(BelongsTo→User)
Production
cuttings → Cutting
id created_by_id(FK→users) status(enum,default:in_progress) description(100,null) total_material_cost(ubig,null) cost_per_unit(ubig,null) created_at updated_at deleted_at
- Casts: status(CuttingStatus), total_material_cost(int), cost_per_unit(int)
- Scopes: cancelled(), completed(), inProgress()
- Relations: createdBy(BelongsTo→User), cuttingMaterialCombinations(HasMany→CuttingMaterialCombination), cuttingMaterials(HasMany→CuttingMaterial), cuttingResults(HasMany→CuttingResult)
cutting_material_combinations → CuttingMaterialCombination
id user_id(FK→users,null) cutting_id(FK→cuttings,null) material_result(int,null) created_at updated_at deleted_at
- Casts: material_result(int)
- Accessor: formatted_material_result → 'X.XXX'
- Relations: cutting(BelongsTo→Cutting), cuttingMaterials(HasMany→CuttingMaterial,combination_id), user(BelongsTo→User)
cutting_materials → CuttingMaterial
id user_id(FK→users,null) cutting_id(FK→cuttings,null) raw_material_price_id(FK→raw_material_prices) combination_id(FK→cutting_material_combinations,null) material_usage(int) material_result(int,null) created_at updated_at deleted_at
- Casts: material_usage(int), material_result(int)
- Accessor: formatted_material_result → 'X.XXX', formatted_material_usage → 'X.XXX'
- Relations: cutting(BelongsTo→Cutting), rawMaterialPrice(BelongsTo→RawMaterialPrice), combination(BelongsTo→CuttingMaterialCombination), user(BelongsTo→User)
cutting_results → CuttingResult
id user_id(FK→users,null) cutting_id(FK→cuttings,null) product_name(255,null) cutting_result(uint,null) sample(uint,null) original_outside_sample(uint,null) created_at updated_at deleted_at
- Casts: cutting_result(int), sample(int), original_outside_sample(int)
- Accessor: formatted_cutting_result → 'X.XXX', formatted_original_outside_sample → 'X.XXX', formatted_sample → 'X.XXX'
- Relations: cutting(BelongsTo→Cutting), user(BelongsTo→User)
Inventory
purchases → Purchase
id supplier_id(FK→suppliers) created_by_id(FK→users) subtotal(ubig) discount(ubig,default:0) shipping_cost(ubig,default:0) total(ubig) notes(100,null) created_at updated_at deleted_at
- Casts: subtotal(int), discount(int), shipping_cost(int), total(int)
- Relations: createdBy(BelongsTo→User), supplier(BelongsTo→Supplier), purchaseItems(HasMany→PurchaseItem)
purchase_items → PurchaseItem
id purchase_id(FK→purchases,null) user_id(FK→users,null) raw_material_price_id(FK→raw_material_prices) quantity(uint) unit_price(ubig) subtotal(ubig) created_at updated_at deleted_at
- Casts: quantity(int), unit_price(int), subtotal(int)
- Relations: purchase(BelongsTo→Purchase), rawMaterialPrice(BelongsTo→RawMaterialPrice,withTrashed), user(BelongsTo→User)
restocks → Restock
id created_by_id(FK→users) subtotal(ubig) total(ubig) notes(100,null) stock_type(enum,default:good) created_at updated_at deleted_at
- Casts: stock_type(ProductStockQuality), subtotal(int), total(int)
- Scopes: good(), reject()
- Relations: createdBy(BelongsTo→User), restockItems(HasMany→RestockItem)
restock_items → RestockItem
id restock_id(FK→restocks,null) user_id(FK→users,null) product_variant_id(FK→product_variants) quantity(int) unit_price(ubig) subtotal(ubig) created_at updated_at deleted_at
- Casts: quantity(int), unit_price(int), subtotal(int)
- Relations: restock(BelongsTo→Restock), productVariant(BelongsTo→ProductVariant), user(BelongsTo→User)
stok_opnames → StokOpname
id created_by_id(FK→users) verified_by_id(FK→users,null) opname_date(date) status(enum,default:draft) notes(text,null) verification_notes(text,null) created_at updated_at deleted_at
- Casts: status(StokOpnameStatus), opname_date(date:Y-m-d)
- Scopes: cancelled(), completed(), draft(), inProgress(), verified()
- Relations: createdBy(BelongsTo→User), verifiedBy(BelongsTo→User), stokOpnameItems(HasMany→StokOpnameItem)
stok_opname_items → StokOpnameItem
id stok_opname_id(FK→stok_opnames) product_variant_id(FK→product_variants) stock_quality(enum,default:good) system_stock(uint,default:0) physical_stock(uint,default:0) difference(int,default:0) notes(text,null) created_at updated_at
- No soft deletes
- Casts: stock_quality(ProductStockQuality), system_stock(int), physical_stock(int), difference(int)
- Scopes: good(), reject()
- Relations: stokOpname(BelongsTo→StokOpname), productVariant(BelongsTo→ProductVariant)
retail_stock_histories → RetailStockHistory
id product_variant_id(FK→product_variants) user_id(FK→users) quantity(uint) stock_before(uint) retail_stock_before(uint) stock_after(uint) retail_stock_after(uint) notes(255,null) created_at
- No soft deletes, no updated_at
- $timestamps = false
- Casts: quantity(int), stock_before(int), retail_stock_before(int), stock_after(int), retail_stock_after(int)
- Accessor: formatted_quantity → 'X.XXX', formatted_retail_stock_before → 'X.XXX', formatted_retail_stock_after → 'X.XXX', formatted_stock_before → 'X.XXX', formatted_stock_after → 'X.XXX'
- Relations: productVariant(BelongsTo→ProductVariant), user(BelongsTo→User)
stock_mutations → StockMutation
id user_id(FK→users) stockable_type(string) stockable_id(ubig) type(string) source_type(string,null) source_id(ubig,null) quantity(int) stock_before(int) stock_after(int) stock_quality(string,null) description(string,null) created_at updated_at
- No soft deletes
- Casts: quantity(int), stock_before(int), stock_after(int)
- Accessor: formatted_quantity → 'X.XXX', formatted_stock_after → 'X.XXX', formatted_stock_before → 'X.XXX'
- Relations: stockable(MorphTo), source(MorphTo), user(BelongsTo→User)
Settings
system_configurations → SystemConfiguration
id created_at updated_at
- Singleton table
homepage_configurations → HomepageConfiguration
id created_at updated_at
- Singleton table
settings (laravel-settings)
id group(string) name(string) locked(bool,default:false) payload(json) created_at updated_at
- UNIQUE(group, name)
Enums
| Enum | Values | Used In |
|---|---|---|
CashTransactionType |
deposit, expense, transfer, withdrawal | cash_transactions.type |
CuttingStatus |
in_progress, completed, cancelled | cuttings.status |
EmployeeAdvanceStatus |
pending, approved, rejected, paid, cancelled | employee_advances.status |
EmploymentStatus |
full_time, part_time, contract, internship, resigned | employees.employment_status |
Gender |
male, female | user_profiles.gender |
LeaveRequestStatus |
pending, approved, rejected, cancelled | leave_requests.status |
Modules |
— | Permission module names |
OrderChannel |
store, shopee, tiktok | orders.channel |
OrderStatus |
pending, processing, completed, cancelled, refunded | orders.status |
PaymentType |
cash, transfer, qris | orders.payment_type |
PayrollAdjustmentType |
bonus, deduction | payroll_adjustments.type |
PayrollPeriodStatus |
open, closed | payroll_periods.status |
PayrollStatus |
unpaid, paid, cancelled | payrolls.status |
Permission |
— | Permission action names |
PriceType |
retail, wholesale, capital | product_prices.type, orders.price_type |
ProductStatus |
active, draft, inactive, pending, rejected | products.status |
ProductStockQuality |
good, reject | order_items.stock_quality, restocks.stock_type, stok_opname_items.stock_quality |
RawMaterialUnit |
kg, meter, yard | raw_materials.unit |
Role |
— | Role names |
StokOpnameStatus |
draft, in_progress, completed, verified, cancelled | stok_opnames.status |
Service Concerns
| Trait | Methods | Used By |
|---|---|---|
HandlesCashTransactions |
getCashAccount(), creditCash(), debitCash() | CashAccountService, ExpenseService, EmployeeAdvanceService, PayrollPeriodService |
HasStockAdjustment |
adjustStock(), adjustVariantStock(), applyStock(), reverseStock() | TransactionService, RestockService |
RegistersMedia |
registerMedia(), syncPhoto() | CashAccountService, CuttingService, ExpenseService, PurchaseService, RestockService, TransactionService |
Form Request Validation Rules
Validasi harus SESUAI dengan DB schema (type + max length).
Master
| Request | Field | Rules | DB Match |
|---|---|---|---|
CategoryRequest |
name |
required, string, max:50, unique:categories,name |
✅ varchar(50) |
CustomerRequest |
name |
required, string, max:200, unique:customers,name |
✅ varchar(200) |
CustomerRequest |
phone_number |
nullable, string, max:20 |
✅ varchar(20) |
CustomerRequest |
address |
nullable, string |
✅ text |
SupplierRequest |
name |
required, string, max:200, unique:suppliers,name |
✅ varchar(200) |
SupplierRequest |
phone_number |
nullable, string, max:20 |
✅ varchar(20) |
RawMaterialRequest |
name |
required, string, max:200 |
✅ varchar(200) |
RawMaterialRequest |
unit |
required, in:kg,meter,yard |
✅ enum |
RawMaterialVariantRequest |
variant |
required, string, max:200 |
✅ varchar(200) |
RawMaterialVariantRequest |
price |
required, integer, min:0 |
✅ uint |
ProductRequest |
name |
required, string, max:200 |
✅ varchar(200) |
ProductVariantRequest |
name |
required, string, max:200 |
✅ varchar(200) |
Finance
| Request | Field | Rules | DB Match |
|---|---|---|---|
CashAccountRequest |
name |
required, string, max:200, unique:cash_accounts,name |
✅ varchar(200) |
CashTransactionRequest |
amount |
required, integer, min:1 |
✅ ubig |
CashTransactionRequest |
description |
required, string, max:100 |
✅ varchar(100) |
ExpenseRequest |
amount |
required, integer, min:1 |
✅ ubig |
ExpenseRequest |
description |
required, string, max:100 |
✅ varchar(100) |
EmployeeAdvanceRequest |
amount |
required, integer, min:1 |
✅ ubig |
EmployeeAdvanceRequest |
description |
required, string, max:100 |
✅ varchar(100) |
EmployeeAdvanceRequest |
due_date |
required, date, after_or_equal:today |
✅ date |
EmployeeAdvancePaymentRequest |
amount |
required, integer, min:1 |
✅ ubig |
EmployeeAdvancePaymentRequest |
description |
nullable, string, max:100 |
✅ varchar(100) nullable |
PayrollAdjustmentRequest |
type |
required, in:bonus,deduction |
✅ enum |
PayrollAdjustmentRequest |
amount |
required, integer, min:1 |
✅ ubig |
PayrollAdjustmentRequest |
description |
required, string, max:100 |
✅ varchar(100) |
HR
| Request | Field | Rules | DB Match |
|---|---|---|---|
EmployeeRequest |
email |
required, email, max:100, unique:users,email |
✅ varchar(100) |
EmployeeRequest |
username |
required, string, max:20, alpha_dash, unique:users,username |
✅ varchar(20) |
EmployeeRequest |
full_name |
required, string, max:200 |
✅ varchar(200) |
EmployeeRequest |
phone_number |
nullable, string, max:20 |
✅ varchar(20) |
EmployeeRequest |
gender |
nullable, in:male,female |
✅ enum |
EmployeeRequest |
base_salary |
required, integer, min:0 |
✅ uint |
AttendanceRequest |
latitude |
required, numeric, min:-90, max:90 |
✅ decimal(10,7) |
AttendanceRequest |
longitude |
required, numeric, min:-180, max:180 |
✅ decimal(10,7) |
LeaveRequestRequest |
start_date |
required, date, after:today |
✅ date |
LeaveRequestRequest |
end_date |
required, date, after_or_equal:start_date |
✅ date |
Sales
| Request | Field | Rules | DB Match |
|---|---|---|---|
TransactionRequest |
channel |
required, in:store,shopee,tiktok |
✅ enum |
TransactionRequest |
price_type |
required, in:retail,wholesale |
✅ enum |
TransactionRequest |
payment_type |
required, in:cash,transfer,qris |
✅ enum |
TransactionRequest |
tiktok_order_id |
nullable, string, max:100 |
✅ varchar(100) |
TransactionRequest |
shopee_order_id |
nullable, string, max:100 |
✅ varchar(100) |
TransactionRequest |
notes |
nullable, string, max:100 |
✅ text (UI limit) |
Production
| Request | Field | Rules | DB Match |
|---|---|---|---|
CuttingRequest |
description |
nullable, string, max:100 |
✅ varchar(100) |
CuttingRequest |
product_name |
required, string, max:255 |
✅ varchar(255) |
CuttingRequest |
cutting_result |
required, integer, min:1 |
✅ uint |
CuttingRequest |
sample |
required, integer |
✅ uint |
CuttingRequest |
original_outside_sample |
required, integer |
✅ uint |
Inventory
| Request | Field | Rules | DB Match |
|---|---|---|---|
PurchaseRequest |
supplier_id |
required, integer, exists:suppliers,id |
✅ FK |
PurchaseRequest |
notes |
nullable, string, max:100 |
✅ varchar(100) |
RestockRequest |
stock_type |
required, in:good,reject |
✅ enum |
RestockRequest |
notes |
nullable, string, max:100 |
✅ varchar(100) |