fixes and additions

This commit is contained in:
2025-12-31 23:38:25 -05:00
parent 147142ad7a
commit 641d987b65
30 changed files with 76 additions and 46 deletions

View File

@@ -189,6 +189,14 @@
<!-- <compilerArgs>&#45;&#45;enable-preview</compilerArgs>--> <!-- <compilerArgs>&#45;&#45;enable-preview</compilerArgs>-->
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<configuration>
<failOnError>false</failOnError>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@@ -2,7 +2,7 @@ package group.goforward.battlbuilder.catalog.classification;
/** /**
* Result returned by PlatformResolver. * Result returned by PlatformResolver.
* * <p>
* Any of the fields may be null — the importer will only overwrite * Any of the fields may be null — the importer will only overwrite
* product.platform, product.partRole, or product.configuration * product.platform, product.partRole, or product.configuration
* when the returned value is non-null AND non-blank. * when the returned value is non-null AND non-blank.

View File

@@ -15,7 +15,7 @@ import java.util.regex.Pattern;
/** /**
* Resolves a product's PLATFORM (e.g. AR-15, AR-10, NOT-SUPPORTED) * Resolves a product's PLATFORM (e.g. AR-15, AR-10, NOT-SUPPORTED)
* using explicit DB-backed rules. * using explicit DB-backed rules.
* * <p>
* Conservative approach: * Conservative approach:
* - If a rule matches, return its target_platform * - If a rule matches, return its target_platform
* - If nothing matches, return null and let the caller decide fallback behavior * - If nothing matches, return null and let the caller decide fallback behavior

View File

@@ -26,7 +26,7 @@ public class BuilderBootstrapController {
/** /**
* Builder bootstrap payload. * Builder bootstrap payload.
* * <p>
* Returns: * Returns:
* - categories: ordered list for UI navigation * - categories: ordered list for UI navigation
* - partRoleMap: normalized partRole -> categorySlug (platform-scoped) * - partRoleMap: normalized partRole -> categorySlug (platform-scoped)

View File

@@ -18,7 +18,7 @@ public class ImportController {
/** /**
* Full product + offer import for a merchant. * Full product + offer import for a merchant.
* * <p>
* POST /admin/imports/{merchantId} * POST /admin/imports/{merchantId}
*/ */
@PostMapping("/{merchantId}") @PostMapping("/{merchantId}")
@@ -29,7 +29,7 @@ public class ImportController {
/** /**
* Offers-only sync (price/stock) for a merchant. * Offers-only sync (price/stock) for a merchant.
* * <p>
* POST /admin/imports/{merchantId}/offers-only * POST /admin/imports/{merchantId}/offers-only
*/ */
@PostMapping("/{merchantId}/offers-only") @PostMapping("/{merchantId}/offers-only")

View File

@@ -10,14 +10,14 @@ import java.util.List;
/** /**
* LEGACY CONTROLLER (Deprecated) * LEGACY CONTROLLER (Deprecated)
* * <p>
* Do not add new features here. * Do not add new features here.
* Canonical API lives in ProductV1Controller (/api/v1/products). * Canonical API lives in ProductV1Controller (/api/v1/products).
* * <p>
* This exists only to keep older clients working temporarily. * This exists only to keep older clients working temporarily.
* Disable by default using: * Disable by default using:
* app.api.legacy.enabled=false * app.api.legacy.enabled=false
* * <p>
* NOTE: * NOTE:
* Even when disabled, Spring still compiles this class. So it must not reference * Even when disabled, Spring still compiles this class. So it must not reference
* missing services/methods. * missing services/methods.

View File

@@ -16,7 +16,14 @@ public class AdminBetaInviteController {
this.betaInviteService = betaInviteService; this.betaInviteService = betaInviteService;
} }
// POST /api/v1/admin/beta/invites/send?limit=25&dryRun=true&tokenMinutes=30 /**
* //api/v1/admin/beta/invites/send?limit=25&dryRun=true&tokenMinutes=30
* @param limit
* @param dryRun
* @param tokenMinutes
* @return
*/
@PostMapping("/invites/send") @PostMapping("/invites/send")
public InviteBatchResponse sendInvites( public InviteBatchResponse sendInvites(
@RequestParam(defaultValue = "0") int limit, @RequestParam(defaultValue = "0") int limit,

View File

@@ -1,7 +1,7 @@
package group.goforward.battlbuilder.controllers.admin; package group.goforward.battlbuilder.controllers.admin;
import group.goforward.battlbuilder.services.admin.impl.AdminDashboardService; import group.goforward.battlbuilder.services.admin.impl.AdminDashboardService;
import group.goforward.battlbuilder.web.dto.AdminDashboardOverviewDto; import group.goforward.battlbuilder.web.dto.admin.AdminDashboardOverviewDto;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;

View File

@@ -1,4 +1,4 @@
package group.goforward.battlbuilder.controllers; package group.goforward.battlbuilder.controllers.admin;
import group.goforward.battlbuilder.model.Platform; import group.goforward.battlbuilder.model.Platform;
import group.goforward.battlbuilder.repos.PlatformRepository; import group.goforward.battlbuilder.repos.PlatformRepository;

View File

@@ -1,5 +1,5 @@
// MerchantAdminController.java // MerchantAdminController.java
package group.goforward.battlbuilder.controllers; package group.goforward.battlbuilder.controllers.admin;
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;

View File

@@ -1,4 +1,4 @@
package group.goforward.battlbuilder.controllers; package group.goforward.battlbuilder.controllers.admin;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;

View File

@@ -1,4 +1,4 @@
package group.goforward.battlbuilder.controllers; package group.goforward.battlbuilder.controllers.api;
import group.goforward.battlbuilder.model.Brand; import group.goforward.battlbuilder.model.Brand;
import group.goforward.battlbuilder.repos.BrandRepository; import group.goforward.battlbuilder.repos.BrandRepository;

View File

@@ -1,4 +1,4 @@
package group.goforward.battlbuilder.controllers; package group.goforward.battlbuilder.controllers.api;
import group.goforward.battlbuilder.model.State; import group.goforward.battlbuilder.model.State;
import group.goforward.battlbuilder.repos.StateRepository; import group.goforward.battlbuilder.repos.StateRepository;

View File

@@ -1,4 +1,4 @@
package group.goforward.battlbuilder.controllers; package group.goforward.battlbuilder.controllers.api;
import group.goforward.battlbuilder.model.User; import group.goforward.battlbuilder.model.User;
import group.goforward.battlbuilder.repos.UserRepository; import group.goforward.battlbuilder.repos.UserRepository;

View File

@@ -1,11 +1,11 @@
/** /*
* Web admin DTOs package for the BattlBuilder application. Web admin DTOs package for the BattlBuilder application.
* <p> <p>
* Contains Data Transfer Objects specific to administrative Contains Data Transfer Objects specific to administrative
* operations including user management, mappings, and platform configuration. operations including user management, mappings, and platform configuration.
*
* @author Forward Group, LLC @author Forward Group, LLC
* @version 1.0 * @version 1.0
* @since 2025-12-10 * @since 2025-12-10
*/ */

View File

@@ -8,7 +8,7 @@ import java.time.OffsetDateTime;
/** /**
* build_profiles * build_profiles
* 1:1 with builds (build_id is both PK and FK) * 1:1 with builds (build_id is both PK and FK)
* * <p>
* Dev notes: * Dev notes:
* - This is the "feed/meta" table for Option B (caliber, class, cover image, tags, etc.) * - This is the "feed/meta" table for Option B (caliber, class, cover image, tags, etc.)
* - Keep it lightweight. Anything social (votes/comments/media) lives elsewhere. * - Keep it lightweight. Anything social (votes/comments/media) lives elsewhere.

View File

@@ -32,7 +32,7 @@ public interface ProductRepository
* Catalog mapping UI: * Catalog mapping UI:
* Returns raw categories for a given merchant + optional platform/q filter, * Returns raw categories for a given merchant + optional platform/q filter,
* along with current merchant_category_map state and canonical category name. * along with current merchant_category_map state and canonical category name.
* * <p>
* Row shape MUST match MappingAdminService mapping: * Row shape MUST match MappingAdminService mapping:
* r[0] merchantId (Integer) * r[0] merchantId (Integer)
* r[1] merchantName (String) * r[1] merchantName (String)

View File

@@ -1,4 +1,4 @@
package group.goforward.battlbuilder.repos.spec; package group.goforward.battlbuilder.repos.catalog.spec;
import group.goforward.battlbuilder.model.Product; import group.goforward.battlbuilder.model.Product;
import group.goforward.battlbuilder.model.ProductStatus; import group.goforward.battlbuilder.model.ProductStatus;

View File

@@ -1,4 +1,4 @@
package group.goforward.battlbuilder.security; package group.goforward.battlbuilder.services;
import group.goforward.battlbuilder.model.User; import group.goforward.battlbuilder.model.User;
import group.goforward.battlbuilder.repos.UserRepository; import group.goforward.battlbuilder.repos.UserRepository;

View File

@@ -4,7 +4,7 @@ import group.goforward.battlbuilder.model.ImportStatus;
import group.goforward.battlbuilder.repos.MerchantCategoryMapRepository; import group.goforward.battlbuilder.repos.MerchantCategoryMapRepository;
import group.goforward.battlbuilder.repos.MerchantRepository; import group.goforward.battlbuilder.repos.MerchantRepository;
import group.goforward.battlbuilder.repos.ProductRepository; import group.goforward.battlbuilder.repos.ProductRepository;
import group.goforward.battlbuilder.web.dto.AdminDashboardOverviewDto; import group.goforward.battlbuilder.web.dto.admin.AdminDashboardOverviewDto;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;

View File

@@ -8,7 +8,7 @@ import group.goforward.battlbuilder.repos.BuildItemRepository;
import group.goforward.battlbuilder.repos.BuildProfileRepository; import group.goforward.battlbuilder.repos.BuildProfileRepository;
import group.goforward.battlbuilder.repos.BuildRepository; import group.goforward.battlbuilder.repos.BuildRepository;
import group.goforward.battlbuilder.repos.ProductOfferRepository; import group.goforward.battlbuilder.repos.ProductOfferRepository;
import group.goforward.battlbuilder.security.CurrentUserService; import group.goforward.battlbuilder.services.CurrentUserService;
import group.goforward.battlbuilder.services.BuildService; import group.goforward.battlbuilder.services.BuildService;
import group.goforward.battlbuilder.web.dto.BuildDto; import group.goforward.battlbuilder.web.dto.BuildDto;
import group.goforward.battlbuilder.web.dto.BuildFeedCardDto; import group.goforward.battlbuilder.web.dto.BuildFeedCardDto;

View File

@@ -4,7 +4,7 @@ import group.goforward.battlbuilder.model.Product;
import group.goforward.battlbuilder.model.ProductOffer; import group.goforward.battlbuilder.model.ProductOffer;
import group.goforward.battlbuilder.repos.ProductOfferRepository; import group.goforward.battlbuilder.repos.ProductOfferRepository;
import group.goforward.battlbuilder.repos.ProductRepository; import group.goforward.battlbuilder.repos.ProductRepository;
import group.goforward.battlbuilder.repos.spec.CatalogProductSpecifications; import group.goforward.battlbuilder.repos.catalog.spec.CatalogProductSpecifications;
import group.goforward.battlbuilder.services.CatalogQueryService; import group.goforward.battlbuilder.services.CatalogQueryService;
import group.goforward.battlbuilder.web.dto.ProductSummaryDto; import group.goforward.battlbuilder.web.dto.ProductSummaryDto;
import group.goforward.battlbuilder.web.dto.catalog.CatalogProductIdsRequest; import group.goforward.battlbuilder.web.dto.catalog.CatalogProductIdsRequest;

View File

@@ -40,14 +40,14 @@ import java.time.Instant;
/** /**
* MerchantFeedImportServiceImpl * MerchantFeedImportServiceImpl
* * <p>
* RESPONSIBILITIES: * RESPONSIBILITIES:
* - Read merchant product feeds (CSV/TSV/etc) * - Read merchant product feeds (CSV/TSV/etc)
* - Normalize product data into Product entities * - Normalize product data into Product entities
* - Resolve PLATFORM (AR-15, AR-10, NOT-SUPPORTED) * - Resolve PLATFORM (AR-15, AR-10, NOT-SUPPORTED)
* - Infer part roles (temporary heuristic) * - Infer part roles (temporary heuristic)
* - Upsert Product + ProductOffer rows * - Upsert Product + ProductOffer rows
* * <p>
* NON-GOALS: * NON-GOALS:
* - Perfect classification (thats iterative) * - Perfect classification (thats iterative)
* - UI-level filtering (handled later) * - UI-level filtering (handled later)

View File

@@ -0,0 +1,11 @@
/**
* Services package for the BattlBuilder application.
* <p>
* Contains business logic service classes for product management,
* category classification, mapping recommendations, and merchant operations.
*
* @author Forward Group, LLC
* @version 1.0
* @since 2025-12-10
*/
package group.goforward.battlbuilder.services.utils;

View File

@@ -3,7 +3,9 @@ package group.goforward.battlbuilder.utils;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* @param <T> * Standard API response wrapper.
*
* @param <T> the type of the data payload
*/ */
public class ApiResponse<T> { public class ApiResponse<T> {

View File

@@ -6,7 +6,7 @@ import java.util.UUID;
/** /**
* Contract for /builds feed cards. * Contract for /builds feed cards.
* Matches the Next.js BuildsPage expectations. * Matches the Next.js BuildsPage expectations.
* * <p>
* Dev Notes: * Dev Notes:
* - We are using Option 2 for money: price is INTEGER CENTS (not dollars). * - We are using Option 2 for money: price is INTEGER CENTS (not dollars).
* Example: $19.99 -> 1999 * Example: $19.99 -> 1999
@@ -38,7 +38,7 @@ public class BuildFeedCardDto {
/** /**
* Estimated build price in CENTS (Option 2). * Estimated build price in CENTS (Option 2).
* Example: 245000 == $2,450.00 * Example: 245000 == $2,450.00
* * <p>
* IMPORTANT: * IMPORTANT:
* - UI must divide by 100 for display. * - UI must divide by 100 for display.
* - Keep nullable optional; treat null as 0 in the UI. * - Keep nullable optional; treat null as 0 in the UI.

View File

@@ -5,7 +5,7 @@ import java.util.List;
/** /**
* Request DTO for creating/updating Build + items. * Request DTO for creating/updating Build + items.
* Keeps entity fields protected from client-side overposting. * Keeps entity fields protected from client-side overposting.
* * <p>
* NOTE: * NOTE:
* - We reuse this for BOTH create (POST /me) and update (PUT /me/{uuid}) for MVP speed. * - We reuse this for BOTH create (POST /me) and update (PUT /me/{uuid}) for MVP speed.
*/ */

View File

@@ -1,4 +1,4 @@
package group.goforward.battlbuilder.web.dto; package group.goforward.battlbuilder.web.dto.admin;
public class AdminDashboardOverviewDto { public class AdminDashboardOverviewDto {

View File

@@ -5,8 +5,10 @@ import group.goforward.battlbuilder.model.ProductStatus;
import group.goforward.battlbuilder.model.ProductVisibility; import group.goforward.battlbuilder.model.ProductVisibility;
/** /**
* Bound from query params on: * Request DTO for searching products in the admin panel.
* GET /api/v1/admin/products?platform=AR-15&q=mini&visibility=PUBLIC... * <p>
* Example:
* GET /api/v1/admin/products?platform=AR-15&amp;q=mini&amp;visibility=PUBLIC
*/ */
public class AdminProductSearchRequest { public class AdminProductSearchRequest {

View File

@@ -1,11 +1,11 @@
/** /*
* Web authentication DTOs package for the BattlBuilder application. Web authentication DTOs package for the BattlBuilder application.
* <p> <p>
* Contains Data Transfer Objects for authentication operations Contains Data Transfer Objects for authentication operations
* including login requests, registration, and authentication responses. including login requests, registration, and authentication responses.
*
* @author Forward Group, LLC @author Forward Group, LLC
* @version 1.0 * @version 1.0
* @since 2025-12-10 * @since 2025-12-10
*/ */