fix: api and structure search fixes

This commit is contained in:
Guarzo
2025-11-12 07:07:39 +00:00
parent d4657b335f
commit 6091adb28e
4 changed files with 77 additions and 39 deletions

View File

@@ -30,9 +30,6 @@ export const SystemStructuresDialog: React.FC<StructuresEditDialogProps> = ({
const { outCommand } = useMapRootState();
const [prevQuery, setPrevQuery] = useState('');
const [prevResults, setPrevResults] = useState<{ label: string; value: string }[]>([]);
useEffect(() => {
if (structure) {
setEditData(structure);
@@ -46,34 +43,24 @@ export const SystemStructuresDialog: React.FC<StructuresEditDialogProps> = ({
// Searching corporation owners via auto-complete
const searchOwners = useCallback(
async (e: { query: string }) => {
const newQuery = e.query.trim();
if (!newQuery) {
const query = e.query.trim();
if (!query) {
setOwnerSuggestions([]);
return;
}
// If user typed more text but we have partial match in prevResults
if (newQuery.startsWith(prevQuery) && prevResults.length > 0) {
const filtered = prevResults.filter(item => item.label.toLowerCase().includes(newQuery.toLowerCase()));
setOwnerSuggestions(filtered);
return;
}
try {
// TODO fix it
const { results = [] } = await outCommand({
type: OutCommand.getCorporationNames,
data: { search: newQuery },
data: { search: query },
});
setOwnerSuggestions(results);
setPrevQuery(newQuery);
setPrevResults(results);
} catch (err) {
console.error('Failed to fetch owners:', err);
setOwnerSuggestions([]);
}
},
[prevQuery, prevResults, outCommand],
[outCommand],
);
const handleChange = (field: keyof StructureItem, val: string | Date) => {
@@ -122,7 +109,6 @@ export const SystemStructuresDialog: React.FC<StructuresEditDialogProps> = ({
// fetch corporation ticker if we have an ownerId
if (editData.ownerId) {
try {
// TODO fix it
const { ticker } = await outCommand({
type: OutCommand.getCorporationTicker,
data: { corp_id: editData.ownerId },

View File

@@ -5,9 +5,36 @@ defmodule WandererApp.Map.Operations.Signatures do
require Logger
alias WandererApp.Map.Operations
alias WandererApp.Api.{MapSystem, MapSystemSignature}
alias WandererApp.Api.{Character, MapSystem, MapSystemSignature}
alias WandererApp.Map.Server
# Private helper to validate character_eve_id from params
# If character_eve_id is provided in params, validates it exists in the system
# If not provided, falls back to the owner's character ID
@spec validate_character_eve_id(map(), String.t()) ::
{:ok, String.t()} | {:error, :invalid_character}
defp validate_character_eve_id(params, fallback_char_id) do
case Map.get(params, "character_eve_id") do
nil ->
# No character_eve_id provided, use fallback (owner's character)
{:ok, fallback_char_id}
provided_char_id when is_binary(provided_char_id) ->
# Validate the provided character_eve_id exists
case Character.by_eve_id(provided_char_id) do
{:ok, _character} ->
{:ok, provided_char_id}
_ ->
{:error, :invalid_character}
end
_ ->
# Invalid format
{:error, :invalid_character}
end
end
@spec list_signatures(String.t()) :: [map()]
def list_signatures(map_id) do
systems = Operations.list_systems(map_id)
@@ -42,10 +69,11 @@ defmodule WandererApp.Map.Operations.Signatures do
)
when is_integer(solar_system_id) do
# Convert solar_system_id to system_id for internal use
with {:ok, system} <- MapSystem.by_map_id_and_solar_system_id(map_id, solar_system_id) do
with {:ok, system} <- MapSystem.by_map_id_and_solar_system_id(map_id, solar_system_id),
{:ok, validated_char_id} <- validate_character_eve_id(params, char_id) do
attrs =
params
|> Map.put("character_eve_id", char_id)
|> Map.put("character_eve_id", validated_char_id)
|> Map.put("system_id", system.id)
|> Map.delete("solar_system_id")
@@ -54,7 +82,7 @@ defmodule WandererApp.Map.Operations.Signatures do
updated_signatures: [],
removed_signatures: [],
solar_system_id: solar_system_id,
character_id: char_id,
character_id: validated_char_id,
user_id: user_id,
delete_connection_with_sigs: false
}) do
@@ -86,6 +114,10 @@ defmodule WandererApp.Map.Operations.Signatures do
{:error, :unexpected_error}
end
else
{:error, :invalid_character} ->
Logger.error("[create_signature] Invalid character_eve_id provided")
{:error, :invalid_character}
_ ->
Logger.error(
"[create_signature] System not found for solar_system_id: #{solar_system_id}"
@@ -112,7 +144,8 @@ defmodule WandererApp.Map.Operations.Signatures do
params
) do
with {:ok, sig} <- MapSystemSignature.by_id(sig_id),
{:ok, system} <- MapSystem.by_id(sig.system_id) do
{:ok, system} <- MapSystem.by_id(sig.system_id),
{:ok, validated_char_id} <- validate_character_eve_id(params, char_id) do
base = %{
"eve_id" => sig.eve_id,
"name" => sig.name,
@@ -120,7 +153,7 @@ defmodule WandererApp.Map.Operations.Signatures do
"group" => sig.group,
"type" => sig.type,
"custom_info" => sig.custom_info,
"character_eve_id" => char_id,
"character_eve_id" => validated_char_id,
"description" => sig.description,
"linked_system_id" => sig.linked_system_id
}
@@ -133,7 +166,7 @@ defmodule WandererApp.Map.Operations.Signatures do
updated_signatures: [attrs],
removed_signatures: [],
solar_system_id: system.solar_system_id,
character_id: char_id,
character_id: validated_char_id,
user_id: user_id,
delete_connection_with_sigs: false
})
@@ -151,6 +184,10 @@ defmodule WandererApp.Map.Operations.Signatures do
_ -> {:ok, attrs}
end
else
{:error, :invalid_character} ->
Logger.error("[update_signature] Invalid character_eve_id provided")
{:error, :invalid_character}
err ->
Logger.error("[update_signature] Unexpected error: #{inspect(err)}")
{:error, :unexpected_error}

View File

@@ -441,18 +441,19 @@ defmodule WandererAppWeb.MapSystemAPIController do
)
def show(%{assigns: %{map_id: map_id}} = conn, %{"id" => id}) do
with {:ok, system_uuid} <- APIUtils.validate_uuid(id),
{:ok, system} <- WandererApp.Api.MapSystem.by_id(system_uuid) do
# Verify the system belongs to the requested map
if system.map_id == map_id do
# Look up by solar_system_id (EVE Online integer ID)
case APIUtils.parse_int(id) do
{:ok, solar_system_id} ->
case Operations.get_system(map_id, solar_system_id) do
{:ok, system} ->
APIUtils.respond_data(conn, APIUtils.map_system_to_json(system))
else
{:error, :not_found} ->
{:error, :not_found}
end
else
{:error, %Ash.Error.Query.NotFound{}} -> {:error, :not_found}
{:error, _} -> {:error, :not_found}
error -> error
{:error, _} ->
{:error, :not_found}
end
end
@@ -472,8 +473,22 @@ defmodule WandererAppWeb.MapSystemAPIController do
)
def create(conn, params) do
systems = Map.get(params, "systems", [])
connections = Map.get(params, "connections", [])
# Support both batch format {"systems": [...], "connections": [...]}
# and single system format {"solar_system_id": ..., ...}
{systems, connections} =
cond do
Map.has_key?(params, "systems") ->
# Batch format
{Map.get(params, "systems", []), Map.get(params, "connections", [])}
Map.has_key?(params, "solar_system_id") or Map.has_key?(params, :solar_system_id) ->
# Single system format - wrap it in an array
{[params], []}
true ->
# Empty request
{[], []}
end
case Operations.upsert_systems_and_connections(conn, systems, connections) do
{:ok, result} ->

View File

@@ -595,7 +595,7 @@ defmodule WandererAppWeb.Router do
# while maintaining 100% backward compatibility with existing /api/* routes
#
scope "/api/v1" do
pipe_through :api_v1
pipe_through [:api_v1, :api_map]
# Custom combined endpoints
get "/maps/:map_id/systems_and_connections",