Implement full CRUD operations for team members with TDD approach: Backend: - TeamMemberController with REST API endpoints - TeamMemberService for business logic extraction - TeamMemberPolicy for authorization (superuser/manager access) - 14 tests passing (8 API, 6 unit tests) Frontend: - Team member list with search and status filter - Create/Edit modal with form validation - Delete confirmation with constraint checking - Currency formatting for hourly rates - Real API integration with teamMemberService Tests: - E2E tests fixed with seed data helper - All 157 tests passing (backend + frontend + E2E) Closes #22
111 lines
4.9 KiB
PHP
111 lines
4.9 KiB
PHP
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
|
<title>Headroom API</title>
|
|
|
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
|
|
|
|
<link rel="stylesheet" href="{{ asset("/vendor/scribe/css/theme-default.style.css") }}" media="screen">
|
|
<link rel="stylesheet" href="{{ asset("/vendor/scribe/css/theme-default.print.css") }}" media="print">
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
|
|
|
|
<link rel="stylesheet"
|
|
href="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/styles/obsidian.min.css">
|
|
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.6.0/highlight.min.js"></script>
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jets/0.14.1/jets.min.js"></script>
|
|
|
|
<style id="language-style">
|
|
/* starts out as display none and is replaced with js later */
|
|
body .content .bash-example code { display: none; }
|
|
body .content .javascript-example code { display: none; }
|
|
</style>
|
|
|
|
<script>
|
|
var tryItOutBaseUrl = "http://localhost/api";
|
|
var useCsrf = Boolean();
|
|
var csrfUrl = "/sanctum/csrf-cookie";
|
|
</script>
|
|
<script src="{{ asset("/vendor/scribe/js/tryitout-5.7.0.js") }}"></script>
|
|
|
|
<script src="{{ asset("/vendor/scribe/js/theme-default-5.7.0.js") }}"></script>
|
|
|
|
</head>
|
|
|
|
<body data-languages="["bash","javascript"]">
|
|
|
|
<a href="#" id="nav-button">
|
|
<span>
|
|
MENU
|
|
<img src="{{ asset("/vendor/scribe/images/navbar.png") }}" alt="navbar-image"/>
|
|
</span>
|
|
</a>
|
|
<div class="tocify-wrapper">
|
|
|
|
<div class="lang-selector">
|
|
<button type="button" class="lang-button" data-language-name="bash">bash</button>
|
|
<button type="button" class="lang-button" data-language-name="javascript">javascript</button>
|
|
</div>
|
|
|
|
<div class="search">
|
|
<input type="text" class="search" id="input-search" placeholder="Search">
|
|
</div>
|
|
|
|
<div id="toc">
|
|
<ul id="tocify-header-introduction" class="tocify-header">
|
|
<li class="tocify-item level-1" data-unique="introduction">
|
|
<a href="#introduction">Introduction</a>
|
|
</li>
|
|
</ul>
|
|
<ul id="tocify-header-authenticating-requests" class="tocify-header">
|
|
<li class="tocify-item level-1" data-unique="authenticating-requests">
|
|
<a href="#authenticating-requests">Authenticating requests</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<ul class="toc-footer" id="toc-footer">
|
|
<li style="padding-bottom: 5px;"><a href="{{ route("scribe.postman") }}">View Postman collection</a></li>
|
|
<li style="padding-bottom: 5px;"><a href="{{ route("scribe.openapi") }}">View OpenAPI spec</a></li>
|
|
<li><a href="http://github.com/knuckleswtf/scribe">Documentation powered by Scribe ✍</a></li>
|
|
</ul>
|
|
|
|
<ul class="toc-footer" id="last-updated">
|
|
<li>Last updated: February 19, 2026</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="page-wrapper">
|
|
<div class="dark-box"></div>
|
|
<div class="content">
|
|
<h1 id="introduction">Introduction</h1>
|
|
<p>Resource planning and capacity management API</p>
|
|
<aside>
|
|
<strong>Base URL</strong>: <code>http://localhost/api</code>
|
|
</aside>
|
|
<pre><code>Authenticate by sending `Authorization: Bearer {access_token}` on protected endpoints.
|
|
|
|
Access tokens are valid for 60 minutes. Use `/api/auth/refresh` with your refresh token to obtain a new access token and refresh token pair.</code></pre>
|
|
|
|
<h1 id="authenticating-requests">Authenticating requests</h1>
|
|
<p>To authenticate requests, include an <strong><code>Authorization</code></strong> header with the value <strong><code>"Bearer Bearer {token}"</code></strong>.</p>
|
|
<p>All authenticated endpoints are marked with a <code>requires authentication</code> badge in the documentation below.</p>
|
|
<p>Get tokens from <code>POST /api/auth/login</code>, send access token as <code>Bearer {token}</code>, and renew with <code>POST /api/auth/refresh</code> before access token expiry.</p>
|
|
|
|
|
|
|
|
</div>
|
|
<div class="dark-box">
|
|
<div class="lang-selector">
|
|
<button type="button" class="lang-button" data-language-name="bash">bash</button>
|
|
<button type="button" class="lang-button" data-language-name="javascript">javascript</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|