fix: merge

This commit is contained in:
ALAMI Adnane 2025-05-07 10:53:02 +02:00
commit e0c43a5c95
13 changed files with 1394 additions and 215 deletions

View File

@ -115,4 +115,15 @@ public class AdminApi {
public Iterable<User> validateEntrepreneurAcc() {
return this.adminApiService.getPendingUsers();
}
@PostMapping("/admin/create-account")
public void createAccount(@AuthenticationPrincipal Jwt principal) {
String userSurname = principal.getClaimAsString("userSurname");
String username = principal.getClaimAsString("preferred_username");
String primaryMail = principal.getClaimAsString("email");
String secondaryMail = principal.getClaimAsString("secondaryMail");
String phoneNumber = principal.getClaimAsString("phoneNumber");
this.adminApiService.createAccount(
userSurname, username, primaryMail, secondaryMail, phoneNumber);
}
}

View File

@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
@ -42,6 +43,19 @@ public class EntrepreneurApi {
sectionCellId, content, principal.getClaimAsString("email"));
}
/**
* Endpoint used to update a LC section.
*
* @return status code
*/
@GetMapping("/entrepreneur/projects")
public Iterable<Project> getEntrepreneurProjectId(
@PathVariable Long sectionCellId,
@RequestBody String content,
@AuthenticationPrincipal Jwt principal) {
return entrepreneurApiService.getProjectIdViaClaim(principal.getClaimAsString("email"));
}
/**
* TODO: checkReturn Type
*

View File

@ -207,6 +207,17 @@ public class AdminApiService {
return this.userService.getPendingAccounts();
}
public void createAccount(
String username,
String userSurname,
String primaryMail,
String secondaryMail,
String phoneNumber) {
Administrator a =
new Administrator(username, userSurname, primaryMail, secondaryMail, phoneNumber);
this.administratorService.addAdministrator(a);
}
public Iterable<Administrator> getAllAdmins() {
return this.administratorService.allAdministrators();
}

View File

@ -15,6 +15,8 @@ import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Service
public class EntrepreneurApiService {
@ -220,6 +222,15 @@ public class EntrepreneurApiService {
throw new ResponseStatusException(HttpStatus.CONFLICT, "User already exists in the system");
}
public Iterable<Project> getProjectIdViaClaim(String email) {
Long UserId = this.userService.getUserByEmail(email).getIdUser();
Entrepreneur entrepreneur = this.entrepreneurService.getEntrepreneurById(UserId);
List<Project> Project_List = new ArrayList<>();
Project_List.add(entrepreneur.getProjectParticipation());
return Project_List;
}
public Iterable<Entrepreneur> getAllEntrepreneurs() {
return entrepreneurService.getAllEntrepreneurs();
}

View File

@ -25,8 +25,9 @@ import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.Map;
@Service
public class SharedApiService {
@ -79,7 +80,7 @@ public class SharedApiService {
LocalDateTime dateTime = LocalDateTime.parse(date, formatter);
Project project = this.projectService.getProjectById(projectId);
return this.sectionCellService.getSectionCellsByProjectAndSectionIdBeforeDate(
return this.sectionCellService.getLatestSectionCellsByIdReferenceBeforeDate(
project, sectionId, dateTime);
}
@ -95,31 +96,36 @@ public class SharedApiService {
}
Project project = this.projectService.getProjectById(projectId);
List<SectionCell> allSectionCells = new ArrayList<SectionCell>();
project.getListSectionCell()
Map<Long, SectionCell> latestSectionCellsMap =
new HashMap<>(); // List for the intermediate result
// Iterate through all SectionCells associated with the project
// This loop iterates over project.getListSectionCell() but does NOT modify it which causes
// ConcurrentModificationException.
// Modifications are done only on the latestSectionCellsMap (which is safe).
project.getListSectionCell() // <-- Iterating over the original list (read-only)
.forEach(
projectCell -> {
AtomicBoolean sameReferenceId =
new AtomicBoolean(false); // side effect lambdas
allSectionCells.forEach(
selectedCell -> {
if (projectCell
.getIdReference()
.equals(selectedCell.getIdReference())) {
sameReferenceId.set(true);
if (projectCell
.getModificationDate()
.isAfter(selectedCell.getModificationDate())) {
allSectionCells.remove(selectedCell);
allSectionCells.add(projectCell);
}
}
});
if (!sameReferenceId.get()) {
allSectionCells.add(projectCell);
Long idReference = projectCell.getIdReference();
// Check if we have already seen a SectionCell with this idReference in
// our map
if (latestSectionCellsMap.containsKey(idReference)) {
SectionCell existingCell = latestSectionCellsMap.get(idReference);
// Compare modification dates. If the current cell is newer, replace
// the one in the map.
if (projectCell
.getModificationDate()
.isAfter(existingCell.getModificationDate())) {
latestSectionCellsMap.put(idReference, projectCell);
}
} else {
// If this is the first time we encounter this idReference, add the
// cell to the map.
latestSectionCellsMap.put(idReference, projectCell);
}
});
return allSectionCells;
return new ArrayList<>(latestSectionCellsMap.values());
}
// TODO: test

View File

@ -14,7 +14,9 @@ import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Service
@ -132,4 +134,37 @@ public class SectionCellService {
return sectionCellRepository.findByProjectSectionCellAndSectionIdAndModificationDateBefore(
project, sectionId, date);
}
public Iterable<SectionCell> getLatestSectionCellsByIdReferenceBeforeDate(
Project project, long sectionId, LocalDateTime date) {
// 1. Fetch ALL relevant SectionCells modified before the date
Iterable<SectionCell> allMatchingCells =
sectionCellRepository.findByProjectSectionCellAndSectionIdAndModificationDateBefore(
project, sectionId, date);
// 2. Find the latest for each idReference
Map<Long, SectionCell> latestCellsByIdReference = new HashMap<>();
for (SectionCell cell : allMatchingCells) {
Long idReference = cell.getIdReference();
// Check if we've seen this idReference before
if (latestCellsByIdReference.containsKey(idReference)) {
// If yes, compare modification dates
SectionCell existingLatest = latestCellsByIdReference.get(idReference);
// If the current cell is more recent, update the map
if (cell.getModificationDate().isAfter(existingLatest.getModificationDate())) {
latestCellsByIdReference.put(idReference, cell);
}
} else {
// If this is the first time we see this idReference, add it to the map
latestCellsByIdReference.put(idReference, cell);
}
}
// 3. Return the collection of the latest cells (the values from the map)
return latestCellsByIdReference.values();
}
}

View File

@ -123,20 +123,6 @@ public class SharedApiServiceTest {
when(mockUtilsService.isAllowedToCheckProject(eq(staticUnauthorizedMail), anyLong()))
.thenReturn(false); // Unauthorized entrepreneur NOT allowed for ANY project ID by
// default
// Add more specific mock setups here if needed for entrepreneur tests
// E.g., If you have a test specifically for an entrepreneur accessing THEIR project:
// Entrepreneur testEntrepreneur =
// entrepreneurService.addEntrepreneur(getTestEntrepreneur("specific_linked_entrepreneur"));
// Project linkedProject =
// projectService.addNewProject(getTestProject("specific_linked_project",
// staticAuthorizedAdmin));
// // Link testEntrepreneur to linkedProject in the database setup...
// when(mockUtilsService.isAllowedToCheckProject(eq(testEntrepreneur.getPrimaryMail()),
// eq(linkedProject.getIdProject()))).thenReturn(true);
// when(mockUtilsService.isAllowedToCheckProject(eq(testEntrepreneur.getPrimaryMail()),
// anyLong())).thenReturn(false); // Deny for other projects
}
// --- Helper Methods (Can remain non-static or static as needed) ---
@ -176,6 +162,17 @@ public class SharedApiServiceTest {
return sectionCell;
}
private static SectionCell getTestSectionCell(
Project project, Long sectionId, String content, LocalDateTime date, Long refrenceId) {
SectionCell sectionCell = new SectionCell();
sectionCell.setProjectSectionCell(project);
sectionCell.setSectionId(sectionId);
sectionCell.setContentSectionCell(content);
sectionCell.setModificationDate(date);
sectionCell.setIdReference(refrenceId);
return sectionCell;
}
private static Appointment getTestAppointment(
LocalDate date,
LocalTime time,
@ -307,6 +304,262 @@ public class SharedApiServiceTest {
assertEquals(HttpStatus.UNAUTHORIZED, exception.getStatusCode());
}
/*
* Tests retrieving section cells for a specific project and section ID before a given date
* when the user is authorized and matching cells exist.
* Verifies that only the correct cells are returned.
*/
@Test
// Commenting out failing test
void testGetSectionCells_Authorized_Found() {
Long targetSectionId = 1L;
// Set a date filter slightly in the future so our "latest before" cell is included
LocalDateTime dateFilter = LocalDateTime.now().plusMinutes(5);
// Creating versions of the SAME SectionCell (share the same idReference)
// the first version. This will get a GENERATED idReference.
SectionCell firstVersion =
getTestSectionCell(
staticAuthorizedProject,
targetSectionId,
"Content V1 (Oldest)",
LocalDateTime.now().minusDays(3) // Oldest date
);
sectionCellService.addNewSectionCell(firstVersion);
Long sharedIdReference = firstVersion.getIdReference();
assertNotNull(
sharedIdReference,
"idReference should be generated after saving the first version");
System.out.println("Generated sharedIdReference: " + sharedIdReference);
// Create subsequent versions and MANUALLY set the SAME idReference.
// These represent updates to the cell identified by sharedIdReference.
SectionCell middleVersion =
getTestSectionCell(
staticAuthorizedProject,
targetSectionId,
"Content V2 (Middle)",
LocalDateTime.now().minusDays(2), // Middle date, before filter
sharedIdReference);
middleVersion = sectionCellService.addNewSectionCell(middleVersion);
sectionCellService.updateSectionCellReferenceId(
middleVersion.getIdSectionCell(), sharedIdReference);
SectionCell latestBeforeFilter =
getTestSectionCell(
staticAuthorizedProject,
targetSectionId,
"Content V3 (Latest Before Filter)",
LocalDateTime.now().minusDays(1), // Latest date before filter
sharedIdReference);
latestBeforeFilter = sectionCellService.addNewSectionCell(latestBeforeFilter);
sectionCellService.updateSectionCellReferenceId(
latestBeforeFilter.getIdSectionCell(), sharedIdReference);
SectionCell futureVersion =
getTestSectionCell(
staticAuthorizedProject,
targetSectionId,
"Content V4 (Future - Should Be Excluded)",
LocalDateTime.now().plusDays(1), // Date is AFTER the filter
sharedIdReference);
futureVersion = sectionCellService.addNewSectionCell(futureVersion);
sectionCellService.updateSectionCellReferenceId(
futureVersion.getIdSectionCell(), sharedIdReference);
// --- Create other SectionCells that should NOT be included (different sectionId or
// project) ---
// Cell in a different section ID
sectionCellService.addNewSectionCell(
getTestSectionCell(
staticAuthorizedProject,
99L, // Different sectionId
"Content in Different Section",
LocalDateTime.now()));
// Act
Iterable<SectionCell> result =
sharedApiService.getSectionCells(
staticAuthorizedProject.getIdProject(), // Use static project ID
targetSectionId,
dateFilter.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
staticAuthorizedMail); // Use static authorized mail
List<SectionCell> resultList = TestUtils.toList(result);
assertEquals(1, resultList.size());
// Verify that the returned cell is the 'latestBeforeFilter' cell
// Comparing by idSectionCell is a good way to verify the exact entity
assertEquals(
latestBeforeFilter.getIdSectionCell(),
resultList.get(0).getIdSectionCell(),
"The returned SectionCell should be the one with the latest modification date before the filter.");
// Also assert the idReference and content
assertEquals(
sharedIdReference,
resultList.get(0).getIdReference(),
"The returned cell should have the shared idReference.");
assertEquals(
"Content V3 (Latest Before Filter)",
resultList.get(0).getContentSectionCell(),
"The returned cell should have the correct content.");
}
/*
* Tests retrieving the most recent section cell for each unique idReference
* within a project when the user is authorized and cells exist.
* Verifies that only the latest version of each referenced cell is returned.
*/
// Tests getAllSectionCells
@Test
// Commenting out failing test - Removed this comment as we are fixing it
void testGetAllSectionCells_Authorized_FoundLatest() {
// Arrange: Create specific SectionCells for this test
// Define the idReference values we will use for grouping
Long refIdGroup1 = 101L;
Long refIdGroup2 = 102L;
Long refIdOtherProject = 103L;
// --- Create and Add Cells for Group 1 (refIdGroup1) ---
// Create the older cell for group 1
SectionCell tempOldCell1 =
getTestSectionCell(
staticAuthorizedProject, // Project
1L, // Section ID (assuming this groups by section within refId)
"Ref1 Old", // Name
LocalDateTime.now().minusDays(3), // Date (older)
null); // Pass null or let getTestSectionCell handle it, we'll set
// idReference later
final SectionCell oldCell1 =
sectionCellService.addNewSectionCell(tempOldCell1); // Add to DB
// Create the newer cell for group 1
SectionCell tempNewerCell1 =
getTestSectionCell(
staticAuthorizedProject, // Project
1L, // Section ID
"Ref1 Newer", // Name
LocalDateTime.now().minusDays(2), // Date (newer than oldCell1)
null); // Pass null
final SectionCell newerCell1 =
sectionCellService.addNewSectionCell(tempNewerCell1); // Add to DB
// Now, update the idReference for both cells in Group 1 to the desired value
sectionCellService.updateSectionCellReferenceId(oldCell1.getIdSectionCell(), refIdGroup1);
sectionCellService.updateSectionCellReferenceId(newerCell1.getIdSectionCell(), refIdGroup1);
// --- Create and Add Cells for Group 2 (refIdGroup2) ---
// Create the older cell for group 2
SectionCell tempOldCell2 =
getTestSectionCell(
staticAuthorizedProject, // Project
2L, // Section ID (different section)
"Ref2 Old", // Name
LocalDateTime.now().minusDays(1), // Date (older than newerCell2)
null); // Pass null
final SectionCell oldCell2 =
sectionCellService.addNewSectionCell(tempOldCell2); // Add to DB
// Create the newer cell for group 2
SectionCell tempNewerCell2 =
getTestSectionCell(
staticAuthorizedProject, // Project
2L, // Section ID
"Ref2 Newer", // Name
LocalDateTime.now(), // Date (latest)
null); // Pass null
final SectionCell newerCell2 =
sectionCellService.addNewSectionCell(tempNewerCell2); // Add to DB
// Now, update the idReference for both cells in Group 2 to the desired value
sectionCellService.updateSectionCellReferenceId(oldCell2.getIdSectionCell(), refIdGroup2);
sectionCellService.updateSectionCellReferenceId(newerCell2.getIdSectionCell(), refIdGroup2);
// --- Create and Add Cell for Other Project (refIdOtherProject) ---
Project otherProject =
projectService.addNewProject(
getTestProject(
"other_project_for_cell_test",
administratorService.addAdministrator(
getTestAdmin("other_admin_cell_test"))));
SectionCell tempOtherProjectCell =
getTestSectionCell(
otherProject, // DIFFERENT Project
1L, // Section ID
"Other Project Cell", // Name
LocalDateTime.now(), // Date
null); // Pass null
final SectionCell otherProjectCell =
sectionCellService.addNewSectionCell(tempOtherProjectCell); // Add to DB
// Now, update the idReference for the Other Project cell
sectionCellService.updateSectionCellReferenceId(
otherProjectCell.getIdSectionCell(), refIdOtherProject);
// Act
// Ensure the service call uses the correct project ID and mail
Iterable<SectionCell> result =
sharedApiService.getAllSectionCells(
staticAuthorizedProject.getIdProject(), // Use static project ID
staticAuthorizedMail); // Use static authorized mail
List<SectionCell> resultList = TestUtils.toList(result);
// Assert
// We expect 2 cells from the staticAuthorizedProject:
// - The latest one from refIdGroup1 (newerCell1)
// - The latest one from refIdGroup2 (newerCell2)
assertEquals(2, resultList.size());
// Assert that the result list contains the LATEST cell from each group within the correct
// project
assertTrue(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(newerCell1.getIdSectionCell())),
"Should contain the latest cell for Group 1"); // Add assertion message
assertTrue(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(newerCell2.getIdSectionCell())),
"Should contain the latest cell for Group 2"); // Add assertion message
// Assert that the result list does NOT contain the OLDER cells from the correct project
assertFalse(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(oldCell1.getIdSectionCell())),
"Should not contain the older cell for Group 1"); // Add assertion message
assertFalse(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(oldCell2.getIdSectionCell())),
"Should not contain the older cell for Group 2"); // Add assertion message
// Assert that the result list does NOT contain the cell from the other project
assertFalse(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(otherProjectCell.getIdSectionCell())),
"Should not contain cells from other projects"); // Add assertion message
}
/*
* _____ _ ____ _ ____ _ _ ____
* |_ _|__ ___| |_ / ___| ___| |_| _ \ _ __ ___ (_) ___ ___| |_| __ ) _ _
@ -605,161 +858,6 @@ public class SharedApiServiceTest {
*/
/* these tests fail because of the use of mockito's eq(),
* and since thee instances are technically not the same as
* as the classes used to turn them into persistant data
* (for e.g id are set by DB) so I have to add some equal functions
* probably and look at peer tests to see what they have done but for now
* I pushed this half-human code.
*/
// --- Test Methods (Use static data from @BeforeAll where possible) ---
/*
* Tests retrieving section cells for a specific project and section ID before a given date
* when the user is authorized and matching cells exist.
* Verifies that only the correct cells are returned.
*/
/*@Test*/
// Commenting out failing test
void testGetSectionCells_Authorized_Found() {
// Arrange: Create specific SectionCells for this test scenario
Long targetSectionId = 1L;
LocalDateTime dateFilter = LocalDateTime.now().plusDays(1);
sectionCellService.addNewSectionCell(
getTestSectionCell(
staticAuthorizedProject,
targetSectionId,
"Old Content",
LocalDateTime.now().minusDays(2)));
SectionCell recentCell =
sectionCellService.addNewSectionCell(
getTestSectionCell(
staticAuthorizedProject,
targetSectionId,
"Recent Content",
LocalDateTime.now().minusDays(1)));
sectionCellService.addNewSectionCell(
getTestSectionCell(
staticAuthorizedProject, 2L, "Other Section", LocalDateTime.now()));
sectionCellService.addNewSectionCell(
getTestSectionCell(
staticAuthorizedProject,
targetSectionId,
"Future Content",
LocalDateTime.now().plusDays(2)));
// Act
Iterable<SectionCell> result =
sharedApiService.getSectionCells(
staticAuthorizedProject.getIdProject(), // Use static project ID
targetSectionId,
dateFilter.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
staticAuthorizedMail); // Use static authorized mail
List<SectionCell> resultList = TestUtils.toList(result);
// Assert
assertEquals(1, resultList.size());
assertEquals(recentCell.getIdSectionCell(), resultList.get(0).getIdSectionCell());
}
/*
* Tests retrieving the most recent section cell for each unique idReference
* within a project when the user is authorized and cells exist.
* Verifies that only the latest version of each referenced cell is returned.
*/
// Tests getAllSectionCells
/*@Test*/
// Commenting out failing test
void testGetAllSectionCells_Authorized_FoundLatest() {
// Arrange: Create specific SectionCells for this test
Long refId1 = 101L;
Long refId2 = 102L;
SectionCell tempOldCell1 =
getTestSectionCell(
staticAuthorizedProject, 1L, "Ref1 Old", LocalDateTime.now().minusDays(3));
tempOldCell1.setIdReference(refId1);
final SectionCell oldCell1 = sectionCellService.addNewSectionCell(tempOldCell1);
SectionCell tempNewerCell1 =
getTestSectionCell(
staticAuthorizedProject,
1L,
"Ref1 Newer",
LocalDateTime.now().minusDays(2));
tempNewerCell1.setIdReference(refId1);
final SectionCell newerCell1 = sectionCellService.addNewSectionCell(tempNewerCell1);
SectionCell tempOldCell2 =
getTestSectionCell(
staticAuthorizedProject, 2L, "Ref2 Old", LocalDateTime.now().minusDays(1));
tempOldCell2.setIdReference(refId2);
final SectionCell oldCell2 = sectionCellService.addNewSectionCell(tempOldCell2);
SectionCell tempNewerCell2 =
getTestSectionCell(staticAuthorizedProject, 2L, "Ref2 Newer", LocalDateTime.now());
tempNewerCell2.setIdReference(refId2);
final SectionCell newerCell2 = sectionCellService.addNewSectionCell(tempNewerCell2);
Project otherProject =
projectService.addNewProject(
getTestProject(
"other_project_for_cell_test",
administratorService.addAdministrator(
getTestAdmin("other_admin_cell_test"))));
SectionCell tempOtherProjectCell =
getTestSectionCell(otherProject, 1L, "Other Project Cell", LocalDateTime.now());
tempOtherProjectCell.setIdReference(103L);
final SectionCell otherProjectCell =
sectionCellService.addNewSectionCell(tempOtherProjectCell);
// Act
Iterable<SectionCell> result =
sharedApiService.getAllSectionCells(
staticAuthorizedProject.getIdProject(), // Use static project ID
staticAuthorizedMail); // Use static authorized mail
List<SectionCell> resultList = TestUtils.toList(result);
// Assert
assertEquals(2, resultList.size()); // Expect 2 cells (one per idReference)
assertTrue(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(newerCell1.getIdSectionCell())));
assertTrue(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(newerCell2.getIdSectionCell())));
assertFalse(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(oldCell1.getIdSectionCell())));
assertFalse(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(oldCell2.getIdSectionCell())));
assertFalse(
resultList.stream()
.anyMatch(
cell ->
cell.getIdSectionCell()
.equals(otherProjectCell.getIdSectionCell())));
}
/*
* Tests retrieving entrepreneurs linked to a project when the user is authorized
* and entrepreneurs are linked.

View File

@ -39,7 +39,7 @@ paths:
schema:
$ref: "./main.yaml#/components/schemas/project"
responses:
"201": # Use 201 Created for successful creation
"200": # Use 200 Created for successful creation
description: Created - Project added successfully. Returns the created project.
content:
application/json:
@ -136,14 +136,6 @@ paths:
If rejected (isAccepted=false), the pending project data might be archived or deleted based on business logic.
security:
- MyINPulse: [MyINPulse-admin]
parameters:
- in: path
name: pendingProjectId # Corrected typo and name change
required: true
schema:
type: integer
description: The ID of the pending project to decide upon.
example: 7
requestBody:
required: true
description: Decision payload.
@ -152,7 +144,7 @@ paths:
schema:
$ref: './main.yaml#/components/schemas/projectDecision'
responses:
"204": # Use 204 No Content for successful action with no body
"200": # Use 200 No Content for successful action with no body
description: No Content - Decision processed successfully.
"400":
description: Bad Request - Invalid input (e.g., missing decision).
@ -199,7 +191,7 @@ paths:
description: The ID of the user account to validate.
example: 102
responses:
"204":
"200":
description: No Content - Account validated successfully.
"400":
description: Bad Request - Invalid user ID format.
@ -255,7 +247,7 @@ paths:
schema:
$ref: "./main.yaml#/components/schemas/report"
responses:
"201":
"200":
description: Created - Report created and linked successfully. Returns the created report.
content:
application/json:
@ -318,7 +310,7 @@ paths:
description: The ID of the project to remove.
example: 12
responses:
"204":
"200":
description: No Content - Project removed successfully.
"400":
description: Bad Request - Invalid project ID format.
@ -345,9 +337,24 @@ paths:
description: The ID of the user to grant admin rights.
example: 103
responses:
"204": # Use 204 No Content
"200": # Use 200 No Content
description: No Content - Admin rights granted successfully.
"400":
description: Bad Request - Invalid user ID format or user is already an admin.
"401":
description: Unauthorized.
/admin/create-account:
post:
summary: Creates Admin out Jwt Token
tags:
- Admin API
security:
- MyINPulse: [MyINPulse-admin]
description: Create an admin instance in the MyINPulse DB of the information provided from the authenticated user's keycloack token.
The information required in the token are `userSurname`, `username`, `primaryMail`, `secondaryMail`, `phoneNumber`.
responses:
"200":
description: No Content - Admin user created successfully.
"401":
description: Unauthorized.

View File

@ -0,0 +1,957 @@
openapi: 3.0.3
info:
title: MyInpulse Backend API
description: 'This serves as an OpenAPI documentation for the MyInpulse backend service, covering operations for Entrepreneurs, Admins, and shared functionalities.'
version: 0.2.1
tags:
- name: Entrepreneurs API
description: API endpoints primarily for Entrepreneur users.
- name: Admin API
description: API endpoints restricted to Admin users for management tasks.
- name: Shared API
description: API endpoints accessible by both Entrepreneurs and Admins.
- name: Unauth API
description: API endpoints related to user account management.
components:
schemas:
user:
type: object
properties:
idUser:
type: integer
description: Unique identifier for the user.
example: 101
userSurname:
type: string
description: User's surname (last name).
example: Doe
userName:
type: string
description: User's given name (first name).
example: John
primaryMail:
type: string
format: email
description: User's primary email address.
example: john.doe@example.com
secondaryMail:
type: string
format: email
description: User's secondary email address (optional).
example: j.doe@personal.com
phoneNumber:
type: string
description: User's phone number.
example: '+33612345678'
user-entrepreneur:
allOf:
- $ref: '#/components/schemas/user'
- type: object
properties:
school:
type: string
description: The school the entrepreneur attends/attended.
example: ENSEIRB-MATMECA
course:
type: string
description: The specific course or program of study.
example: Electronics
sneeStatus:
type: boolean
description: Indicates if the user has SNEE status (Statut National d'Étudiant-Entrepreneur).
example: true
example:
idUser: 101
userSurname: Doe
userName: John
primaryMail: john.doe@example.com
secondaryMail: j.doe@personal.com
phoneNumber: '+33612345678'
school: ENSEIRB-MATMECA
course: Electronics
sneeStatus: true
user-admin:
allOf:
- $ref: '#/components/schemas/user'
example:
idUser: 55
userSurname: Admin
userName: Super
primaryMail: admin@myinpulse.com
phoneNumber: '+33512345678'
sectionCell:
type: object
description: Represents a cell (like a sticky note) within a specific section of a project's Lean Canvas.
properties:
idSectionCell:
type: integer
description: Unique identifier for the section cell.
example: 508
sectionId:
type: integer
description: 'Identifier of the Lean Canvas section this cell belongs to (e.g., 1 for Problem, 2 for Solution).'
example: 1
contentSectionCell:
type: string
description: The text content of the section cell.
example: Users find it hard to track project progress.
modificationDate:
type: string
format: date
description: The date when this cell was last modified.
example: 'yyyy-MM-dd HH:mm'
project:
type: object
description: Represents a project being managed or developed.
properties:
idProject:
type: integer
description: Unique identifier for the project.
example: 12
projectName:
type: string
description: The name of the project.
example: MyInpulse Mobile App
creationDate:
type: string
format: date
description: The date when the project was created in the system.
example: 'yyyy-MM-dd HH:mm'
logo:
type: string
format: byte
description: Base64 encoded string representing the project logo image.
example: /*Base64 encoded string representing the project logo image*/
status:
type: string
enum:
- PENDING
- ACTIVE
- ENDED
- ABORTED
- REJECTED
description: 'Corresponds to a status enum internal to the backend, it''s value in in requests incoming to the server should be ignored as the client shouldn''t be specifying them.'
example: NaN
report:
type: object
description: Represents a report associated with an appointment.
properties:
idReport:
type: integer
description: Unique identifier for the report.
example: 987
reportContent:
type: string
description: The textual content of the report. Could be plain text or Markdown (specify if known).
example: Discussed roadmap milestones for Q3. Agreed on preliminary UI mockups.
appointment:
type: object
description: Represents a scheduled meeting or appointment.
properties:
idAppointment:
type: integer
description: Unique identifier for the appointment.
example: 303
appointmentDate:
type: string
format: date
description: The date of the appointment.
example: '2025-05-10'
appointmentTime:
type: string
format: time
description: The time of the appointment (local time).
example: '14:30:00'
appointmentDuration:
type: string
description: 'Duration of the appointment in ISO 8601 duration format (e.g., PT1H30M for 1 hour 30 minutes).'
example: PT1H
appointmentPlace:
type: string
description: Location or meeting link for the appointment.
example: 'Meeting Room 3 / https://meet.example.com/abc-def-ghi'
appointmentSubject:
type: string
description: The main topic or subject of the appointment.
example: Q3 Roadmap Planning
joinRequest:
type: object
description: Represents a request from an entrepreneur to join an already existing project.
properties:
idProject:
type: integer
description: the ID of the project the entrepreneur wants to join.
example: 42
entrepreneur:
$ref: '#/components/schemas/user-entrepreneur'
projectDecision:
type: object
description: Represents a decision from an admin to accept a pending project.
properties:
projectId:
type: integer
description: The ID of the project the entrepreneur wants to join.
example: 12
adminId:
type: integer
description: The ID of the project the admin who will supervise the project in case of admission.
example: 2
isAccepted:
type: boolean
description: The boolean value of the decision.
example: 'true'
joinRequestDecision:
type: object
description: Represents a decision from an admin to accept a pending project join request.
properties:
isAccepted:
type: boolean
description: The boolean value of the decision.
example: 'true'
securitySchemes:
MyINPulse:
type: oauth2
description: OAuth2 authentication using Keycloak.
flows:
implicit:
authorizationUrl: '{keycloakBaseUrl}/realms/{keycloakRealm}/protocol/openid-connect/auth'
scopes:
MyINPulse-admin: Grants administrator access.
MyINPulse-entrepreneur: Grants standard entrepreneur user access.
servers:
- url: '{serverProtocol}://{serverHost}:{serverPort}'
description: API Server
variables:
serverProtocol:
enum:
- http
- https
default: http
serverHost:
default: localhost
serverPort:
enum:
- '8081'
default: '8081'
keycloakBaseUrl:
default: 'http://localhost:7080'
description: Base URL for the Keycloak server.
keycloakRealm:
default: MyInpulseRealm
description: Keycloak realm name.
paths:
/unauth/finalize:
post:
summary: Finalize account setup using authentication token
description: |-
Completes the user account creation/setup process in the MyInpulse system.
This endpoint requires the user to be authenticated via Keycloak (e.g., after initial login).
User details (name, email, etc.) are extracted from the authenticated user's token (e.g., Keycloak JWT).
No request body is needed. The account is marked as pending admin validation upon successful finalization.
tags:
- Unauth API
responses:
'200':
description: Created - Account finalized and pending admin validation. Returns the user profile.
'400':
description: Bad Request - Problem processing the token or user data derived from it.
'401':
description: Unauthorized - Valid authentication token required.
'/unauth/request-join/{projectId}':
post:
summary: Request to join an existing project
description: Submits a request for the authenticated user (keycloack authenticated) to join the project specified by projectId. Their role is then changed to entrepreneur in server and Keycloak. This requires approval from a project admin.
tags:
- Unauth API
parameters:
- in: path
name: projectId
required: true
schema:
type: integer
description: The ID of the project to request joining.
example: 15
responses:
'200':
description: Accepted - Join request submitted and pending approval.
'400':
description: Bad Request - Invalid project ID format
'401':
description: Unauthorized.
'409':
description: Already member/request pending.
/admin/pending-accounts:
get:
operationId: getPendingAccounts
summary: Get accounts awaiting validation
description: Retrieves a list of entrepreneur user accounts that are pending admin validation.
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
responses:
'200':
description: OK - List of pending accounts returned.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/user-entrepreneur'
'401':
description: Unauthorized.
'/admin/accounts/validate/{userId}':
post:
operationId: validateUserAccount
summary: Validate a pending user account
description: Marks the user account specified by userId as validated/active.
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
parameters:
- in: path
name: userId
required: true
schema:
type: integer
description: The ID of the user account to validate.
example: 102
responses:
'200':
description: No Content - Account validated successfully.
'400':
description: Bad Request - Invalid user ID format.
'401':
description: Unauthorized.
/admin/request-join:
get:
operationId: getPendingProjects
summary: Get entrepreneurs project join requests
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
description: Retrieves a list of pending requests from entrepreneurs to join an existing project.
responses:
'200':
description: OK - List of pending project join requests.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/joinRequest'
'401':
description: Unauthorized.
'/admin/request-join/decision/{joinRequestId}':
post:
summary: Approve or reject a pending project join request
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
parameters:
- in: path
name: joinRequestId
required: true
schema:
type: integer
description: The ID of the pending join request to decide upon.
description: |-
Allows an admin to make a decision on an ebtrepreneur's request to join an existing project awaiting validation.
If approved (isAccepted=true), the entrepreneur is linked to the project with ID joinRequestId.
If rejected (isAccepted=false), the pending request data might be archived or deleted based on business logic.
responses:
'200':
description: 'OK - No Content, decision processed successfully..'
content:
application/json:
$ref: '#/components/schemas/joinRequestDecision'
'400':
description: 'Bad Request - Invalid input (e.g., missing decision).'
'401':
description: Unauthorized.
/admin/projects:
get:
operationId: getAdminProjects
summary: Get projects associated with the admin
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
description: 'Retrieves a list of projects managed by the requesting admin, including details for overview.'
responses:
'200':
description: OK - List of projects returned successfully.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/project'
'400':
description: 'Bad Request - Invalid project data provided (e.g., missing required fields).'
'401':
description: Unauthorized - Authentication required or invalid token.
post:
operationId: addProjectManually
summary: Manually add a new project
description: 'Creates a new project with the provided details. (NOTE that this meant for manually inserting projects, for example importing already existing projects).'
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
requestBody:
required: true
description: Project details to create. `idProject` and `creationDate` will be ignored if sent and set by the server.
content:
application/json:
schema:
$ref: '#/components/schemas/project'
responses:
'200':
description: Created - Project added successfully. Returns the created project.
content:
application/json:
schema:
$ref: '#/components/schemas/project'
'401':
description: Unauthorized.
'409':
description: Bad Request - Project already exists.
/admin/projects/pending:
get:
operationId: getPendingProjects
summary: Get projects awaiting validation
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
description: Retrieves a list of projects submitted by entrepreneurs that are pending admin approval.
responses:
'200':
description: OK - List of pending projects returned.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/project'
'401':
description: Unauthorized.
/admin/projects/pending/decision:
post:
operationId: decidePendingProject
summary: Approve or reject a pending project
tags:
- Admin API
description: |-
Allows an admin to make a decision on a project awaiting validation.
If approved (isAccepted=true), the project status changes, and it's linked to the involved users.
If rejected (isAccepted=false), the pending project data might be archived or deleted based on business logic.
security:
- MyINPulse:
- MyINPulse-admin
requestBody:
required: true
description: Decision payload.
content:
application/json:
schema:
$ref: '#/components/schemas/projectDecision'
responses:
'200':
description: No Content - Decision processed successfully.
'400':
description: 'Bad Request - Invalid input (e.g., missing decision).'
'401':
description: Unauthorized.
'/admin/appointments/report/{appointmentId}':
post:
operationId: createAppointmentReport
summary: Create a report for an appointment
description: 'Creates and links a new report (e.g., meeting minutes) to the specified appointment using the provided content.'
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
parameters:
- in: path
name: appointmentId
required: true
schema:
type: integer
description: ID of the appointment to add a report to.
example: 303
requestBody:
required: true
description: Report content. `idReport` will be ignored if sent.
content:
application/json:
schema:
$ref: '#/components/schemas/report'
responses:
'200':
description: Created - Report created and linked successfully. Returns the created report.
content:
application/json:
schema:
$ref: '#/components/schemas/report'
'400':
description: 'Bad Request - Invalid input (e.g., missing content, invalid appointment ID format).'
'401':
description: Unauthorized.
put:
operationId: updateAppointmentReport
summary: Update an existing appointment report
description: Updates the content of an existing report linked to the specified appointment. Replaces the entire report content.
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
parameters:
- in: path
name: appointmentId
required: true
schema:
type: integer
description: ID of the appointment whose report needs updating.
example: 303
requestBody:
required: true
description: New report content. `idReport` in the body should match the existing report's ID or will be ignored.
content:
application/json:
schema:
$ref: '#/components/schemas/report'
responses:
'200':
description: OK - Report updated successfully. Returns the updated report.
content:
application/json:
schema:
$ref: '#/components/schemas/report'
'400':
description: 'Bad Request - Invalid input (e.g., missing content).'
'401':
description: Unauthorized.
/admin/appointments/upcoming:
get:
operationId: getUpcomingAppointments
summary: Get upcoming appointments for an admin
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
description: Retrieves a list of appointments scheduled for an admin in the future.
responses:
'200':
description: OK - List of upcoming appointments.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/appointment'
'401':
description: Unauthorized.
'404':
description: no appointments found.
'/admin/projects/{projectId}':
delete:
operationId: removeProject
summary: Remove a project
description: Permanently removes the project specified by projectId and potentially related data (use with caution).
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
parameters:
- in: path
name: projectId
required: true
schema:
type: integer
description: The ID of the project to remove.
example: 12
responses:
'200':
description: No Content - Project removed successfully.
'400':
description: Bad Request - Invalid project ID format.
'401':
description: Unauthorized.
'/admin/make-admin/{userId}':
post:
operationId: grantAdminRights
summary: Grant admin rights to a user
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
description: Elevates the specified user to also have administrator privileges. Assumes the user already exists.
parameters:
- in: path
name: userId
required: true
schema:
type: integer
description: The ID of the user to grant admin rights.
example: 103
responses:
'200':
description: No Content - Admin rights granted successfully.
'400':
description: Bad Request - Invalid user ID format or user is already an admin.
'401':
description: Unauthorized.
/admin/create-account:
post:
summary: Creates Admin out Jwt Token
tags:
- Admin API
security:
- MyINPulse:
- MyINPulse-admin
description: 'Create an admin instance in the MyINPulse DB of the information provided from the authenticated user''s keycloack token. The information required in the token are `userSurname`, `username`, `primaryMail`, `secondaryMail`, `phoneNumber`.'
responses:
'200':
description: No Content - Admin user created successfully.
'401':
description: Unauthorized.
'/shared/projects/sectionCells/{projectId}/{sectionId}/{date}':
get:
operationId: getSectionCellsByDate
summary: Get project section cells modified on a specific date
tags:
- Shared API
security:
- MyINPulse:
- MyINPulse-entrepreneur
- MyINPulse-admin
description: 'Retrieves section cells belonging to a specific section of a project, filtered by the last modification date. Requires user to have access to the project.'
parameters:
- in: path
name: projectId
required: true
schema:
type: integer
description: ID of the project.
- in: path
name: sectionId
required: true
schema:
type: integer
description: ID of the Lean Canvas section.
- in: path
name: date
required: true
schema:
type: string
format: date
description: 'The modification date to filter by (YYYY-MM-DD HH:mm).'
responses:
'200':
description: OK - List of section cells matching the criteria.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/sectionCell'
'400':
description: Bad Request - Invalid parameter format.
'401':
description: Unauthorized.
'/shared/projects/entrepreneurs/{projectId}':
get:
operationId: getProjectEntrepreneurs
summary: Get entrepreneurs associated with a project
tags:
- Shared API
security:
- MyINPulse:
- MyINPulse-entrepreneur
- MyINPulse-admin
description: Retrieves a list of entrepreneur users associated with the specified project. Requires access to the project.
parameters:
- in: path
name: projectId
required: true
schema:
type: integer
description: ID of the project.
responses:
'200':
description: OK - List of entrepreneurs.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/user-entrepreneur'
'401':
description: Unauthorized.
'403':
description: Forbidden - User does not have access to this project.
'404':
description: Not Found - Project not found.
'/shared/projects/admin/{projectId}':
get:
operationId: getProjectAdmin
summary: Get admin associated with a project
tags:
- Shared API
security:
- MyINPulse:
- MyINPulse-entrepreneur
- MyINPulse-admin
description: Retrieves a list of admin users associated with the specified project. Requires access to the project.
parameters:
- in: path
name: projectId
required: true
schema:
type: integer
description: ID of the project.
responses:
'200':
description: OK - admin.
content:
application/json:
schema:
$ref: '#/components/schemas/user-admin'
'401':
description: Unauthorized.
'403':
description: Forbidden - User does not have access to this project.
'404':
description: Not Found - Project not found.
'/shared/projects/appointments/{projectId}':
get:
operationId: getProjectAppointments
summary: Get appointments related to a project
tags:
- Shared API
security:
- MyINPulse:
- MyINPulse-entrepreneur
- MyINPulse-admin
description: Retrieves a list of appointments associated with the specified project. Requires access to the project.
parameters:
- in: path
name: projectId
required: true
schema:
type: integer
description: ID of the project.
responses:
'200':
description: OK - List of appointments.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/appointment'
'401':
description: Unauthorized.
'/shared/appointments/report/{appointmentId}':
get:
operationId: getAppointmentReport
summary: Get the report for an appointment
tags:
- Shared API
security:
- MyINPulse:
- MyINPulse-entrepreneur
- MyINPulse-admin
description: Retrieves the report associated with a specific appointment. Requires user to have access to the appointment/project.
parameters:
- in: path
name: appointmentId
required: true
schema:
type: integer
description: ID of the appointment.
responses:
'200':
description: OK - Report PDF returned.
content:
application/pdf:
schema:
schema: null
type: string
format: binary
'401':
description: Unauthorized.
/shared/appointments/request:
post:
operationId: requestAppointment
summary: Request a new appointment
tags:
- Shared API
security:
- MyINPulse:
- MyINPulse-entrepreneur
- MyINPulse-admin
description: 'Allows a user (entrepreneur or admin) to request a new appointment, potentially with another user or regarding a project. Details in the body. The request might need confirmation or create a pending appointment.'
requestBody:
required: true
description: Details of the appointment request.
content:
application/json:
schema:
$ref: '#/components/schemas/appointment'
responses:
'200':
description: Accepted - Appointment request submitted.
'400':
description: Bad Request - Invalid appointment details.
'401':
description: Unauthorized.
/entrepreneur/projects:
get:
summary: gets the projectId of the project associated with the entrepreneur
description: returns a list of projectIds of the projects associated with the entrepreneur
tags:
- Entrepreneurs API
security:
- MyINPulse:
- MyINPulse-entrepreneur
parameters: null
responses:
'200':
description: OK - Section cell updated successfully. Returns the updated cell.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/project'
'401':
description: Unauthorized or identity not found
'404':
description: Bad Request - Invalid input or ID mismatch.
/entrepreneur/projects/request:
post:
operationId: requestProjectCreation
summary: Request creation and validation of a new project
tags:
- Entrepreneurs API
description: |-
Submits a request for a new project. The project details are provided in the request body.
The requesting entrepreneur (identified by the token) will be associated to it.
The project is created with a 'pending' status, awaiting admin approval.
security:
- MyINPulse:
- MyINPulse-entrepreneur
requestBody:
required: true
description: 'Project details for the request. `status`, `creationDate` are required by the model when being sent but is ignored by the server; primarily expects a valid `projectId`, `name`, `logo`.'
content:
application/json:
schema:
$ref: '#/components/schemas/project'
responses:
'200':
description: Accepted - Project creation request received and is pending validation.
'400':
description: 'Bad Request - Invalid input (e.g., missing name).'
'401':
description: Unauthorized.
/entrepreneur/sectionCells:
post:
operationId: addSectionCell
summary: Add a cell to a Lean Canvas section
description: Adds a new cell (like a sticky note) with the provided content to a specific section of the entrepreneur's project's Lean Canvas. Assumes project context is known based on user's token. `idSectionCell` and `modificationDate` are server-generated so they're values in the request are ignored by the server.
tags:
- Entrepreneurs API
security:
- MyINPulse:
- MyINPulse-entrepreneur
requestBody:
required: true
description: Section cell details. `idSectionCell` and `modificationDate` will be ignored if sent.
content:
application/json:
schema:
$ref: '#/components/schemas/sectionCell'
responses:
'200':
description: Created - Section cell added successfully. Returns the created cell.
'400':
description: 'Bad Request - Invalid input (e.g., missing content or sectionId).'
'401':
description: Unauthorized.
'/entrepreneur/sectionCells/{sectionCellId}':
put:
operationId: modifySectionCell
summary: Modify data in a Lean Canvas section cell
description: Updates the content of an existing Lean Canvas section cell specified by `sectionCellId`. The server "updates" (it keeps a record of the previous version to keep a history of all the sectionCells and creates a new ones with the specified modifications) the `modificationDate`.
tags:
- Entrepreneurs API
security:
- MyINPulse:
- MyINPulse-entrepreneur
parameters:
- in: path
name: sectionCellId
required: true
schema:
type: integer
description: The ID of the section cell to modify.
example: 508
requestBody:
required: true
description: Updated section cell details. `sectionCellId` "the path parameter" is the only id that's consideredn the `sectionCellId` id in the request body is ignored. `modificationDate` should be updated by the server.
content:
application/json:
schema:
$ref: '#/components/schemas/sectionCell'
responses:
'200':
description: OK - Section cell updated successfully. Returns the updated cell.
'401':
description: Unauthorized.
'404':
description: Bad Request - Invalid input or ID mismatch.
delete:
operationId: removeSectionCell
summary: Remove a Lean Canvas section cell
description: Deletes the Lean Canvas section cell specified by `sectionCellId`.
tags:
- Entrepreneurs API
security:
- MyINPulse:
- MyINPulse-entrepreneur
parameters:
- in: path
name: sectionCellId
required: true
schema:
type: integer
description: The ID of the section cell to remove.
example: 509
responses:
'200':
description: No Content - Section cell removed successfully.
'400':
description: Bad Request - Invalid ID format.
'401':
description: Unauthorized.
'404':
description: Bad Request - sectionCell not found.

View File

@ -21,7 +21,7 @@ paths:
schema:
$ref: "./main.yaml#/components/schemas/project"
responses:
"202":
"200":
description: Accepted - Project creation request received and is pending validation.
"400":
description: Bad Request - Invalid input (e.g., missing name).
@ -46,7 +46,7 @@ paths:
schema:
$ref: "./main.yaml#/components/schemas/sectionCell"
responses:
"201":
"200":
description: Created - Section cell added successfully. Returns the created cell.
"400":
description: Bad Request - Invalid input (e.g., missing content or sectionId).
@ -102,7 +102,7 @@ paths:
description: The ID of the section cell to remove.
example: 509
responses:
"204":
"200":
description: No Content - Section cell removed successfully.
"400":
description: Bad Request - Invalid ID format.
@ -110,3 +110,27 @@ paths:
description: Bad Request - sectionCell not found.
"401":
description: Unauthorized.
/entrepreneur/projects:
get:
summary: gets the projectId of the project associated with the entrepreneur
description: returns a list of projectIds of the projects associated with the entrepreneur
tags:
- Entrepreneurs API
security:
- MyINPulse: [MyINPulse-entrepreneur]
parameters:
responses:
"200":
description: OK - Section cell updated successfully. Returns the updated cell.
content:
application/json:
schema:
type: array
items:
$ref: "./main.yaml#/components/schemas/project"
"404":
description: Bad Request - Invalid input or ID mismatch.
"401":
description: Unauthorized or identity not found

View File

@ -108,6 +108,8 @@ paths:
$ref: "./adminApi.yaml#/paths/~1admin~1projects~1{projectId}"
/admin/make-admin/{userId}:
$ref: "./adminApi.yaml#/paths/~1admin~1make-admin~1{userId}"
/admin/create-account:
$ref: "./adminApi.yaml#/paths/~1admin~1create-account"
# ____ _ _ _ ____ ___
# / ___|| |__ __ _ _ __ ___ __| | / \ | _ \_ _|
@ -138,6 +140,9 @@ paths:
# / ___ \| __/| |
# /_/ \_\_| |___|
#
/entrepreneur/projects:
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1projects"
/entrepreneur/projects/request:
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1projects~1request"
/entrepreneur/sectionCells:

View File

@ -176,7 +176,7 @@ paths:
$ref: "./main.yaml#/components/schemas/appointment" # Assuming request uses same model structure
# Potentially add projectId or targetUserId here
responses:
"202": # Accepted seems appropriate for a request
"200": # Accepted seems appropriate for a request
description: Accepted - Appointment request submitted.
"400":
description: Bad Request - Invalid appointment details.

View File

@ -18,7 +18,7 @@ paths:
tags:
- Unauth API
responses:
"201":
"200":
description: Created - Account finalized and pending admin validation. Returns the user profile.
"400":
description: Bad Request - Problem processing the token or user data derived from it.
@ -39,7 +39,7 @@ paths:
description: The ID of the project to request joining.
example: 15
responses: # Moved responses block to correct level
"202":
"200":
description: Accepted - Join request submitted and pending approval.
"400":
description: Bad Request - Invalid project ID format
@ -54,7 +54,7 @@ paths:
tags:
- Unauth API
responses:
"202":
"200":
description: Accepted - Become admin request submitted and pending approval.
"400":
description: Bad Request - Invalid project ID format or already member/request pending.