Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .codex/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ command = "C:\\Users\\jamius19\\miniconda3\\envs\\awsmcp\\Scripts\\awslabs.opena
args = ["--spec-url", "http://localhost:8080/v3/api-docs"]
enabled = true

[mcp_servers.flightdrift_openapi.tools.getOrganizations]
approval_mode = "approve"

[sandbox_workspace_write]
network_access = true
5 changes: 4 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ Check `AGENTS.md` file within each application dir (i.e., `flightdrift-frontend/

Keep your changes as small as possible and always ask before making a big change.

When you create/modify any endpoint, update the relavant yml file(s) in the `api-collection\Flightdrift` OpenCollection directory.
When you create/modify any endpoint, update the relavant yml file(s) in the `api-collection\Flightdrift` OpenCollection directory.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"relavant" should be "relevant".

📝 Proposed fix
-When you create/modify any endpoint, update the relavant yml file(s) in the `api-collection\Flightdrift` OpenCollection directory.
+When you create/modify any endpoint, update the relevant yml file(s) in the `api-collection\Flightdrift` OpenCollection directory.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
When you create/modify any endpoint, update the relavant yml file(s) in the `api-collection\Flightdrift` OpenCollection directory.
When you create/modify any endpoint, update the relevant yml file(s) in the `api-collection\Flightdrift` OpenCollection directory.
🧰 Tools
🪛 LanguageTool

[grammar] ~11-~11: Ensure spelling is correct
Context: ... create/modify any endpoint, update the relavant yml file(s) in the `api-collection\Flig...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 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 `@AGENTS.md` at line 11, Fix the spelling error in AGENTS.md by replacing the
misspelled word "relavant" with the correct word "relevant" in the sentence that
instructs updating the yml files for the `api-collection\Flightdrift`
OpenCollection directory; ensure the corrected sentence reads "When you
create/modify any endpoint, update the relevant yml file(s)..." and keep the
rest of the line unchanged.


## Tools
1. Check if `rg` is available, if so use it, otherwise use `grep`.
10 changes: 8 additions & 2 deletions api-collection/Flightdrift/Auth/Sign In.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ runtime:
code: |-
var jsonData = res.getBody();

bru.set("auth_token", jsonData.data.token);
bru.setEnvVar("auth_token", jsonData.data.token);

settings:
encodeUrl: true
Expand Down Expand Up @@ -73,6 +73,12 @@ examples:
"success": true,
"message": "Signed in successfully",
"data": {
"token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJqYW1pdXMxOSIsImlhdCI6MTc3OTkwMjgxMiwiZXhwIjoxODY2MzAyODEyfQ.Y0Rca6ESQvV16n_VJxP4rzxVERvRaSzonuOFTfyD0Ytz1H4cMEnQ-crukQ0i0l_Bwf72m_aCUfqSamdABNB6Vg"
"token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJqYW1pdXMxOSIsImlhdCI6MTc3OTkwMjgxMiwiZXhwIjoxODY2MzAyODEyfQ.Y0Rca6ESQvV16n_VJxP4rzxVERvRaSzonuOFTfyD0Ytz1H4cMEnQ-crukQ0i0l_Bwf72m_aCUfqSamdABNB6Vg",
Comment thread
jamius19 marked this conversation as resolved.
"userInfo": {
"id": "0c71345a-0a0f-42a5-88dc-43616f65d5e3",
"name": "Jamius Siam",
"email": "jamius@example.com",
"username": "jamius19"
}
}
}
8 changes: 4 additions & 4 deletions api-collection/Flightdrift/Auth/Signup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ http:
data: |-
{
"name": "Jamius Siam",
"email": "jamiussiam@gmail.com",
"email": "jamius@example.com",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"username": "jamius19",
"password": "123"
}
Expand All @@ -32,7 +32,7 @@ examples:
data: |-
{
"name": "Jamius Siam",
"email": "jamiussiam@gmail.com",
"email": "jamius@example.com",
"username": "jamius19",
"password": "123"
}
Expand Down Expand Up @@ -69,9 +69,9 @@ examples:
"success": true,
"message": "Account created successfully",
"data": {
"id": "019e6a79-5e97-7b4d-9f53-b7d0e4a3f96c",
"id": "019e73b4-33b7-74fd-ad65-3bd068e2e46c",
"name": "Jamius Siam",
"email": "jamiussiam@gmail.com",
"email": "jamius@example.com",
"username": "jamius19"
}
}
3 changes: 3 additions & 0 deletions api-collection/Flightdrift/Project/Create Project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ http:
data: |-
{
"name": "Flightdrift",
"code": "ARTEMIS",
"iconUrl": "https://example.com/project.png"
}
auth: inherit
Expand Down Expand Up @@ -42,6 +43,7 @@ examples:
data: |-
{
"name": "Flightdrift",
"code": "ARTEMIS",
"iconUrl": "https://example.com/project.png"
}
response:
Expand All @@ -60,6 +62,7 @@ examples:
"project": {
"id": "019e6a80-e269-7ddc-9e6b-d25eccfd192d",
"name": "Flightdrift",
"code": "ARTEMIS",
"iconUrl": "https://example.com/project.png",
"organizationId": "019e6a80-6593-7416-8876-dec6b99510ab"
}
Expand Down
3 changes: 3 additions & 0 deletions api-collection/Flightdrift/Project/Edit Project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ http:
data: |-
{
"name": "Flightdrift HQ",
"code": "ARTEMIS",
"iconUrl": "https://example.com/project-updated.png"
}
auth: inherit
Expand All @@ -34,6 +35,7 @@ examples:
data: |-
{
"name": "Flightdrift HQ",
"code": "ARTEMIS",
"iconUrl": "https://example.com/project-updated.png"
}
response:
Expand All @@ -52,6 +54,7 @@ examples:
"project": {
"id": "019e6a80-e269-7ddc-9e6b-d25eccfd192d",
"name": "Flightdrift HQ",
"code": "ARTEMIS",
"iconUrl": "https://example.com/project-updated.png",
"organizationId": "019e6a80-6593-7416-8876-dec6b99510ab"
}
Expand Down
1 change: 1 addition & 0 deletions api-collection/Flightdrift/Project/Get Projects.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ examples:
{
"id": "019e6a80-e269-7ddc-9e6b-d25eccfd192d",
"name": "Flightdrift",
"code": "ARTEMIS",
"iconUrl": "https://example.com/project.png",
"organizationId": "019e6a80-6593-7416-8876-dec6b99510ab"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name: Flightdrift-Dev
2 changes: 0 additions & 2 deletions api-collection/Flightdrift/opencollection.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ request:
value: 019e6a80-e269-7ddc-9e6b-d25eccfd192d
- name: item_id
value: 019b7a23-58a7-72f0-bdea-b39d8ab32191
- name: auth_token
value: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJqYW1pdXMxOSIsImlhdCI6MTc3OTkwMjgxMiwiZXhwIjoxODY2MzAyODEyfQ.Y0Rca6ESQvV16n_VJxP4rzxVERvRaSzonuOFTfyD0Ytz1H4cMEnQ-crukQ0i0l_Bwf72m_aCUfqSamdABNB6Vg
bundled: false
extensions:
bruno:
Expand Down
3 changes: 3 additions & 0 deletions db/migration/1. account.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ CREATE TABLE account
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE account OWNER TO flightdrift;

CREATE TABLE blacklisted_auth_token
(
Expand All @@ -23,3 +24,5 @@ CREATE TABLE blacklisted_auth_token
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE blacklisted_auth_token OWNER TO flightdrift;
4 changes: 4 additions & 0 deletions db/migration/2. organization.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ CREATE TABLE organization
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE organization OWNER TO flightdrift;

CREATE TABLE account_organization_mapping
(
id UUID PRIMARY KEY DEFAULT uuidv7(),
Expand All @@ -23,3 +25,5 @@ CREATE TABLE account_organization_mapping
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE account_organization_mapping OWNER TO flightdrift;
3 changes: 3 additions & 0 deletions db/migration/3. project.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ CREATE TABLE project
(
id UUID PRIMARY KEY DEFAULT uuidv7(),
name VARCHAR(50) NOT NULL,
code VARCHAR(10) NOT NULL,
icon_url VARCHAR(1024),
organization_id UUID REFERENCES organization (id) NOT NULL,
version BIGINT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE project OWNER TO flightdrift;

CREATE INDEX idx_project_organization_id ON project (organization_id);
2 changes: 2 additions & 0 deletions db/migration/4. item.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ CREATE TABLE item
)
);

ALTER TABLE item OWNER TO flightdrift;

CREATE INDEX idx_item_project_id ON item (project_id);
2 changes: 2 additions & 0 deletions db/migration/5. flag.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ CREATE TABLE flag
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE flag OWNER TO flightdrift;
2 changes: 2 additions & 0 deletions db/migration/6. setting.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ CREATE TABLE setting
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE setting OWNER TO flightdrift;
17 changes: 8 additions & 9 deletions flightdrift-backend/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ This is a Java 25 Spring Boot 4 project for a kanban-inspired project management

## Rules for Development
1. Use Java 25 LTS features.
2. Do not try to compile and test unless I ask you to.
3. Use the `dto.com.flightdrift.flightdrift.ApiResponse` class for API responses.
4. Add new lines between each instance variables of a class.
5. Use Lombok and Jakarta persistence annotations where applicable.
6. Use Lombok's `@Builder` when creating entites.
7. DB related sql files can be found under `db/migration`

## Tools
1. Check if `rg` is available, if so use it, otherwise use `grep`.
2. Compile to check for errors without running tests.
3. Do not run tests for now.
4. Use the `dto.com.flightdrift.flightdrift.ApiResponse` class for API responses.
5. Update the OpenCollection files at `api-collection/Flightdrift` when adding/updating endpoints.
6. Add new lines between each instance variable of a class.
7. Use Lombok and Jakarta persistence annotations where applicable.
8. Use Lombok's `@Builder` when creating entities.
9. DB related SQL files can be found under `db/migration`
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/*
* Author: Jamius Siam
Expand Down Expand Up @@ -55,4 +57,14 @@ public PasswordEncoder passwordEncoder() {
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}

@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
Comment thread
jamius19 marked this conversation as resolved.
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.flightdrift.flightdrift.dto.auth.InvitationTokenResponse;
import com.flightdrift.flightdrift.dto.auth.SignupResponse;
import com.flightdrift.flightdrift.dto.auth.TokenResponse;
import com.flightdrift.flightdrift.dto.auth.UserInfoResponse;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
Expand Down Expand Up @@ -91,11 +92,22 @@ public ResponseEntity<ApiResponse<?>> signin(@Valid @RequestBody SigninRequest s

UserDetails userDetails = userDetailsService.loadUserByUsername(signinRequest.username());
String token = jwtUtil.generateToken(userDetails);
Account account = accountRepository
.findByUsername(userDetails.getUsername())
.orElseThrow(() -> new IllegalStateException("Authenticated account not found"));
Comment thread
coderabbitai[bot] marked this conversation as resolved.

return ResponseEntity.ok(new ApiResponse<>(
true,
"Signed in successfully",
new TokenResponse(token)
new TokenResponse(
token,
new UserInfoResponse(
account.getId(),
account.getName(),
account.getEmail(),
account.getUsername()
)
)
));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
* Author: Jamius Siam
* Since: 06/05/2026
*/
public record TokenResponse(String token) {
public record TokenResponse(
String token,
UserInfoResponse userInfo
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.flightdrift.flightdrift.dto.auth;

import java.util.UUID;

/*
* Author: Jamius Siam
* Since: 29/05/2026
*/
public record UserInfoResponse(
UUID id,
String name,
String email,
String username
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public record CreateProjectRequest(
@Size(max = 50, message = "Name must not exceed 50 characters")
String name,

@NotBlank(message = "Code is required")
@Size(max = 10, message = "Code must not exceed 10 characters")
String code,

@Size(max = 1024, message = "Icon URL must not exceed 1024 characters")
String iconUrl
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public record EditProjectRequest(
@Size(max = 50, message = "Name must not exceed 50 characters")
String name,

@NotBlank(message = "Code is required")
@Size(max = 10, message = "Code must not exceed 10 characters")
String code,

@Size(max = 1024, message = "Icon URL must not exceed 1024 characters")
String iconUrl
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
public record ProjectResponse(
UUID id,
String name,
String code,
String iconUrl,
UUID organizationId
) {
public static ProjectResponse fromEntity(Project project) {
return new ProjectResponse(
project.getId(),
project.getName(),
project.getCode(),
project.getIconUrl(),
project.getOrganization().getId()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public class Project extends Auditable {
@Column(nullable = false, length = 50)
private String name;

@Column(nullable = false, length = 10)
private String code;

@Column(name = "icon_url", length = 1024)
private String iconUrl;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.flightdrift.flightdrift.exception;

import com.flightdrift.flightdrift.dto.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.server.ResponseStatusException;

import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;

/*
* Author: Jamius Siam
* Since: 30/05/2026
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<ApiResponse<?>> handleResponseStatusException(ResponseStatusException exception) {
String message = exception.getReason() == null ? exception.getMessage() : exception.getReason();

return ResponseEntity
.status(exception.getStatusCode())
.body(new ApiResponse<>(false, message, null));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<?>> handleException(Exception exception) {
log.error("Unhandled exception", exception);

return ResponseEntity
.status(INTERNAL_SERVER_ERROR)
.body(new ApiResponse<>(false, "Internal server error", null));
}
}
Loading