mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-11-30 04:53:24 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
802e81b1cd | ||
|
|
41f0834c51 | ||
|
|
880de0b047 | ||
|
|
bbe7fda4e0 | ||
|
|
92a9274dce | ||
|
|
8765d83083 | ||
|
|
a298152bc8 | ||
|
|
2b7abe5774 | ||
|
|
3e9241892e | ||
|
|
6ea79a7960 | ||
|
|
2af562e313 | ||
|
|
40672f6a47 | ||
|
|
6d66ae3f50 | ||
|
|
94c89e0325 | ||
|
|
3670ef40a3 | ||
|
|
16d464fba5 | ||
|
|
0b7e0b9cd0 | ||
|
|
dd5fd114d2 | ||
|
|
6e53879344 | ||
|
|
af2bfd4d59 |
42
.github/workflows/build.yml
vendored
42
.github/workflows/build.yml
vendored
@@ -18,49 +18,8 @@ permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
deploy-test:
|
||||
name: 🚀 Deploy to test env (fly.io)
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.base_ref == 'main' || (github.ref == 'refs/heads/main' && github.event_name == 'push') }}
|
||||
steps:
|
||||
- name: ⬇️ Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
- uses: superfly/flyctl-actions/setup-flyctl@master
|
||||
|
||||
- name: 👀 Read app name
|
||||
uses: SebRollen/toml-action@v1.0.0
|
||||
id: app_name
|
||||
with:
|
||||
file: "fly.toml"
|
||||
field: "app"
|
||||
|
||||
- name: 🚀 Deploy Test
|
||||
run: flyctl deploy --remote-only --wait-timeout=300 --ha=false
|
||||
env:
|
||||
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
|
||||
|
||||
manual-approval:
|
||||
name: Manual Approval
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy-test
|
||||
if: success()
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- name: Await Manual Approval
|
||||
uses: trstringer/manual-approval@v1
|
||||
with:
|
||||
secret: ${{ github.TOKEN }}
|
||||
approvers: DmitryPopov
|
||||
minimum-approvals: 1
|
||||
issue-title: "Manual Approval Required for Release"
|
||||
issue-body: "Please approve or deny the deployment."
|
||||
|
||||
build:
|
||||
name: 🛠 Build
|
||||
needs: manual-approval
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ (github.ref == 'refs/heads/main') && github.event_name == 'push' }}
|
||||
permissions:
|
||||
@@ -157,7 +116,6 @@ jobs:
|
||||
matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
|
||||
56
CHANGELOG.md
56
CHANGELOG.md
@@ -2,6 +2,62 @@
|
||||
|
||||
<!-- changelog -->
|
||||
|
||||
## [v1.65.7](https://github.com/wanderer-industries/wanderer/compare/v1.65.6...v1.65.7) (2025-05-26)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: Fixed map character tracking issues
|
||||
|
||||
## [v1.65.6](https://github.com/wanderer-industries/wanderer/compare/v1.65.5...v1.65.6) (2025-05-26)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: Fixed map character tracking issues
|
||||
|
||||
## [v1.65.5](https://github.com/wanderer-industries/wanderer/compare/v1.65.4...v1.65.5) (2025-05-26)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Core: Fixed map character tracking issues
|
||||
|
||||
* Signature: Update restored signature character
|
||||
|
||||
## [v1.65.4](https://github.com/wanderer-industries/wanderer/compare/v1.65.3...v1.65.4) (2025-05-24)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Signature: Force signature update even if there are no any changes
|
||||
|
||||
## [v1.65.3](https://github.com/wanderer-industries/wanderer/compare/v1.65.2...v1.65.3) (2025-05-23)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Signature: Fixed signature clenup
|
||||
|
||||
## [v1.65.2](https://github.com/wanderer-industries/wanderer/compare/v1.65.1...v1.65.2) (2025-05-23)
|
||||
|
||||
|
||||
|
||||
|
||||
### Bug Fixes:
|
||||
|
||||
* Signature: Fixed signature updates
|
||||
|
||||
## [v1.65.1](https://github.com/wanderer-industries/wanderer/compare/v1.65.0...v1.65.1) (2025-05-22)
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { UNKNOWN_SIGNATURE_NAME } from '@/hooks/Mapper/helpers';
|
||||
import { SystemSignature } from '@/hooks/Mapper/types';
|
||||
import { SignatureGroup, SystemSignature } from '@/hooks/Mapper/types';
|
||||
|
||||
export const getState = (_: string[], newSig: SystemSignature) => {
|
||||
let state = -1;
|
||||
if (!newSig.group) {
|
||||
if (!newSig.group || newSig.group === SignatureGroup.CosmicSignature) {
|
||||
state = 0;
|
||||
} else if (!newSig.name || newSig.name === '' || newSig.name === UNKNOWN_SIGNATURE_NAME) {
|
||||
state = 1;
|
||||
} else if (newSig.name !== '') {
|
||||
state = 2;
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@ export const useSystemSignaturesData = ({
|
||||
? signaturesRef.current.filter(sig => !sig.pendingDeletion)
|
||||
: signaturesRef.current.filter(sig => !sig.pendingDeletion || !sig.pendingAddition);
|
||||
|
||||
const { added, updated, removed } = getActualSigs(currentNonPending, incomingSignatures, !lazyDeleteValue, true);
|
||||
const { added, updated, removed } = getActualSigs(currentNonPending, incomingSignatures, !lazyDeleteValue, false);
|
||||
|
||||
if (removed.length > 0) {
|
||||
await processRemovedSignatures(removed, added, updated);
|
||||
|
||||
@@ -3,17 +3,19 @@ defmodule WandererApp.Api.MapCharacterSettings do
|
||||
|
||||
use Ash.Resource,
|
||||
domain: WandererApp.Api,
|
||||
data_layer: AshPostgres.DataLayer
|
||||
data_layer: AshPostgres.DataLayer,
|
||||
extensions: [AshCloak]
|
||||
|
||||
@derive {Jason.Encoder, only: [
|
||||
:id,
|
||||
:map_id,
|
||||
:character_id,
|
||||
:tracked,
|
||||
:followed,
|
||||
:inserted_at,
|
||||
:updated_at
|
||||
]}
|
||||
@derive {Jason.Encoder,
|
||||
only: [
|
||||
:id,
|
||||
:map_id,
|
||||
:character_id,
|
||||
:tracked,
|
||||
:followed,
|
||||
:inserted_at,
|
||||
:updated_at
|
||||
]}
|
||||
|
||||
postgres do
|
||||
repo(WandererApp.Repo)
|
||||
@@ -23,8 +25,10 @@ defmodule WandererApp.Api.MapCharacterSettings do
|
||||
code_interface do
|
||||
define(:create, action: :create)
|
||||
define(:destroy, action: :destroy)
|
||||
define(:update, action: :update)
|
||||
|
||||
define(:read_by_map, action: :read_by_map)
|
||||
define(:read_by_map_and_character, action: :read_by_map_and_character)
|
||||
define(:by_map_filtered, action: :by_map_filtered)
|
||||
define(:tracked_by_map_filtered, action: :tracked_by_map_filtered)
|
||||
define(:tracked_by_character, action: :tracked_by_character)
|
||||
@@ -44,7 +48,31 @@ defmodule WandererApp.Api.MapCharacterSettings do
|
||||
:tracked
|
||||
]
|
||||
|
||||
defaults [:create, :read, :update, :destroy]
|
||||
defaults [:read, :destroy]
|
||||
|
||||
create :create do
|
||||
primary? true
|
||||
upsert? true
|
||||
upsert_identity :uniq_map_character
|
||||
|
||||
upsert_fields [
|
||||
:map_id,
|
||||
:character_id
|
||||
]
|
||||
|
||||
accept [
|
||||
:map_id,
|
||||
:character_id,
|
||||
:tracked,
|
||||
:followed
|
||||
]
|
||||
|
||||
argument :map_id, :uuid, allow_nil?: false
|
||||
argument :character_id, :uuid, allow_nil?: false
|
||||
|
||||
change manage_relationship(:map_id, :map, on_lookup: :relate, on_no_match: nil)
|
||||
change manage_relationship(:character_id, :character, on_lookup: :relate, on_no_match: nil)
|
||||
end
|
||||
|
||||
read :by_map_filtered do
|
||||
argument(:map_id, :string, allow_nil?: false)
|
||||
@@ -67,6 +95,15 @@ defmodule WandererApp.Api.MapCharacterSettings do
|
||||
filter(expr(map_id == ^arg(:map_id)))
|
||||
end
|
||||
|
||||
read :read_by_map_and_character do
|
||||
get? true
|
||||
|
||||
argument(:map_id, :string, allow_nil?: false)
|
||||
argument(:character_id, :uuid, allow_nil?: false)
|
||||
|
||||
filter(expr(map_id == ^arg(:map_id) and character_id == ^arg(:character_id)))
|
||||
end
|
||||
|
||||
read :tracked_by_map_all do
|
||||
argument(:map_id, :string, allow_nil?: false)
|
||||
filter(expr(map_id == ^arg(:map_id) and tracked == true))
|
||||
@@ -77,6 +114,20 @@ defmodule WandererApp.Api.MapCharacterSettings do
|
||||
filter(expr(character_id == ^arg(:character_id) and tracked == true))
|
||||
end
|
||||
|
||||
update :update do
|
||||
primary? true
|
||||
require_atomic? false
|
||||
|
||||
accept([
|
||||
:ship,
|
||||
:ship_name,
|
||||
:ship_item_id,
|
||||
:solar_system_id,
|
||||
:structure_id,
|
||||
:station_id
|
||||
])
|
||||
end
|
||||
|
||||
update :track do
|
||||
accept [:map_id, :character_id]
|
||||
argument :map_id, :string, allow_nil?: false
|
||||
@@ -134,6 +185,28 @@ defmodule WandererApp.Api.MapCharacterSettings do
|
||||
end
|
||||
end
|
||||
|
||||
cloak do
|
||||
vault(WandererApp.Vault)
|
||||
|
||||
attributes([
|
||||
:ship,
|
||||
:ship_name,
|
||||
:ship_item_id,
|
||||
:solar_system_id,
|
||||
:structure_id,
|
||||
:station_id
|
||||
])
|
||||
|
||||
decrypt_by_default([
|
||||
:ship,
|
||||
:ship_name,
|
||||
:ship_item_id,
|
||||
:solar_system_id,
|
||||
:structure_id,
|
||||
:station_id
|
||||
])
|
||||
end
|
||||
|
||||
attributes do
|
||||
uuid_primary_key :id
|
||||
|
||||
@@ -147,6 +220,13 @@ defmodule WandererApp.Api.MapCharacterSettings do
|
||||
allow_nil? true
|
||||
end
|
||||
|
||||
attribute :solar_system_id, :integer
|
||||
attribute :structure_id, :integer
|
||||
attribute :station_id, :integer
|
||||
attribute :ship, :integer
|
||||
attribute :ship_name, :string
|
||||
attribute :ship_item_id, :integer
|
||||
|
||||
create_timestamp(:inserted_at)
|
||||
update_timestamp(:updated_at)
|
||||
end
|
||||
|
||||
@@ -25,9 +25,18 @@ defmodule WandererApp.Api.MapSystemSignature do
|
||||
|
||||
define(:by_system_id, action: :by_system_id, args: [:system_id])
|
||||
define(:by_system_id_all, action: :by_system_id_all, args: [:system_id])
|
||||
define(:by_system_id_and_eve_ids, action: :by_system_id_and_eve_ids, args: [:system_id, :eve_ids])
|
||||
|
||||
define(:by_system_id_and_eve_ids,
|
||||
action: :by_system_id_and_eve_ids,
|
||||
args: [:system_id, :eve_ids]
|
||||
)
|
||||
|
||||
define(:by_linked_system_id, action: :by_linked_system_id, args: [:linked_system_id])
|
||||
define(:by_deleted_and_updated_before!, action: :by_deleted_and_updated_before, args: [:deleted, :updated_before])
|
||||
|
||||
define(:by_deleted_and_updated_before!,
|
||||
action: :by_deleted_and_updated_before,
|
||||
args: [:deleted, :updated_before]
|
||||
)
|
||||
end
|
||||
|
||||
actions do
|
||||
@@ -88,7 +97,8 @@ defmodule WandererApp.Api.MapSystemSignature do
|
||||
:group,
|
||||
:type,
|
||||
:custom_info,
|
||||
:deleted
|
||||
:deleted,
|
||||
:update_forced_at
|
||||
]
|
||||
|
||||
primary? true
|
||||
@@ -177,6 +187,10 @@ defmodule WandererApp.Api.MapSystemSignature do
|
||||
default false
|
||||
end
|
||||
|
||||
attribute :update_forced_at, :utc_datetime do
|
||||
allow_nil? true
|
||||
end
|
||||
|
||||
create_timestamp(:inserted_at)
|
||||
update_timestamp(:updated_at)
|
||||
end
|
||||
@@ -192,21 +206,20 @@ defmodule WandererApp.Api.MapSystemSignature do
|
||||
end
|
||||
|
||||
@derive {Jason.Encoder,
|
||||
only: [
|
||||
:id,
|
||||
:system_id,
|
||||
:eve_id,
|
||||
:character_eve_id,
|
||||
:name,
|
||||
:description,
|
||||
:type,
|
||||
:linked_system_id,
|
||||
:kind,
|
||||
:group,
|
||||
:custom_info,
|
||||
:deleted,
|
||||
:inserted_at,
|
||||
:updated_at
|
||||
]
|
||||
}
|
||||
only: [
|
||||
:id,
|
||||
:system_id,
|
||||
:eve_id,
|
||||
:character_eve_id,
|
||||
:name,
|
||||
:description,
|
||||
:type,
|
||||
:linked_system_id,
|
||||
:kind,
|
||||
:group,
|
||||
:custom_info,
|
||||
:deleted,
|
||||
:inserted_at,
|
||||
:updated_at
|
||||
]}
|
||||
end
|
||||
|
||||
@@ -7,6 +7,15 @@ defmodule WandererApp.Character do
|
||||
@read_character_wallet_scope "esi-wallet.read_character_wallet.v1"
|
||||
@read_corp_wallet_scope "esi-wallet.read_corporation_wallets.v1"
|
||||
|
||||
@default_character_tracking_data %{
|
||||
solar_system_id: nil,
|
||||
structure_id: nil,
|
||||
station_id: nil,
|
||||
ship: nil,
|
||||
ship_name: nil,
|
||||
ship_item_id: nil
|
||||
}
|
||||
|
||||
@decorate cacheable(
|
||||
cache: WandererApp.Cache,
|
||||
key: "characters-#{character_eve_id}"
|
||||
@@ -45,6 +54,32 @@ defmodule WandererApp.Character do
|
||||
end
|
||||
end
|
||||
|
||||
def get_map_character(map_id, character_id) do
|
||||
case get_character(character_id) do
|
||||
{:ok, character} ->
|
||||
{:ok,
|
||||
character
|
||||
|> maybe_merge_map_character_settings(
|
||||
map_id,
|
||||
WandererApp.Character.TrackerManager.Impl.character_is_present(map_id, character_id)
|
||||
)}
|
||||
|
||||
_ ->
|
||||
{:ok, nil}
|
||||
end
|
||||
end
|
||||
|
||||
def get_map_character!(map_id, character_id) do
|
||||
case get_map_character(map_id, character_id) do
|
||||
{:ok, character} ->
|
||||
character
|
||||
|
||||
_ ->
|
||||
Logger.error("Failed to get map character #{map_id} #{character_id}")
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def get_character_eve_ids!(character_ids),
|
||||
do:
|
||||
character_ids
|
||||
@@ -146,7 +181,7 @@ defmodule WandererApp.Character do
|
||||
params: opts[:params]
|
||||
) do
|
||||
{:ok, result} ->
|
||||
{:ok, result |> _prepare_search_results()}
|
||||
{:ok, result |> prepare_search_results()}
|
||||
|
||||
{:error, error} ->
|
||||
Logger.warning("#{__MODULE__} failed search: #{inspect(error)}")
|
||||
@@ -208,7 +243,28 @@ defmodule WandererApp.Character do
|
||||
end
|
||||
end
|
||||
|
||||
defp _prepare_search_results(result) do
|
||||
defp maybe_merge_map_character_settings(character, map_id, true), do: character
|
||||
|
||||
defp maybe_merge_map_character_settings(
|
||||
%{id: character_id} = character,
|
||||
map_id,
|
||||
_character_is_present
|
||||
) do
|
||||
WandererApp.MapCharacterSettingsRepo.get(map_id, character_id)
|
||||
|> case do
|
||||
{:ok, settings} when not is_nil(settings) ->
|
||||
character
|
||||
|> Map.put(:online, false)
|
||||
|> Map.merge(settings)
|
||||
|
||||
_ ->
|
||||
character
|
||||
|> Map.put(:online, false)
|
||||
|> Map.merge(@default_character_tracking_data)
|
||||
end
|
||||
end
|
||||
|
||||
defp prepare_search_results(result) do
|
||||
{:ok, characters} =
|
||||
_load_eve_info(Map.get(result, "character"), :get_character_info, &_map_character_info/1)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ defmodule WandererApp.Character.TrackerManager.Impl do
|
||||
}
|
||||
|
||||
@garbage_collection_interval :timer.minutes(15)
|
||||
@untrack_characters_interval :timer.minutes(5)
|
||||
@untrack_characters_interval :timer.minutes(1)
|
||||
@inactive_character_timeout :timer.minutes(5)
|
||||
|
||||
@logger Application.compile_env(:wanderer_app, :logger)
|
||||
@@ -220,6 +220,18 @@ defmodule WandererApp.Character.TrackerManager.Impl do
|
||||
track: false
|
||||
})
|
||||
|
||||
{:ok, character} = WandererApp.Character.get_character(character_id)
|
||||
|
||||
{:ok, _updated} =
|
||||
WandererApp.MapCharacterSettingsRepo.update(map_id, character_id, %{
|
||||
ship: character.ship,
|
||||
ship_name: character.ship_name,
|
||||
ship_item_id: character.ship_item_id,
|
||||
solar_system_id: character.solar_system_id,
|
||||
structure_id: character.structure_id,
|
||||
station_id: character.station_id
|
||||
})
|
||||
|
||||
WandererApp.Character.update_character_state(character_id, character_state)
|
||||
end
|
||||
end,
|
||||
@@ -246,7 +258,7 @@ defmodule WandererApp.Character.TrackerManager.Impl do
|
||||
def handle_info(_event, state),
|
||||
do: state
|
||||
|
||||
defp character_is_present(map_id, character_id) do
|
||||
def character_is_present(map_id, character_id) do
|
||||
{:ok, presence_character_ids} =
|
||||
WandererApp.Cache.lookup("map_#{map_id}:presence_character_ids", [])
|
||||
|
||||
|
||||
@@ -121,7 +121,6 @@ defmodule WandererApp.Character.TrackingUtils do
|
||||
WandererApp.MapCharacterSettingsRepo.untrack(existing_settings)
|
||||
|
||||
:ok = untrack([character], map_id, caller_pid)
|
||||
:ok = remove_characters([character], map_id)
|
||||
{:ok, updated_settings}
|
||||
else
|
||||
{:ok, existing_settings}
|
||||
@@ -132,7 +131,6 @@ defmodule WandererApp.Character.TrackingUtils do
|
||||
if track do
|
||||
{:ok, updated_settings} = WandererApp.MapCharacterSettingsRepo.track(existing_settings)
|
||||
:ok = track([character], map_id, true, caller_pid)
|
||||
:ok = add_characters([character], map_id, true)
|
||||
{:ok, updated_settings}
|
||||
else
|
||||
{:ok, existing_settings}
|
||||
@@ -149,7 +147,6 @@ defmodule WandererApp.Character.TrackingUtils do
|
||||
})
|
||||
|
||||
:ok = track([character], map_id, true, caller_pid)
|
||||
:ok = add_characters([character], map_id, true)
|
||||
{:ok, settings}
|
||||
else
|
||||
{:error, "Character settings not found"}
|
||||
@@ -231,15 +228,15 @@ defmodule WandererApp.Character.TrackingUtils do
|
||||
with false <- is_nil(caller_pid) do
|
||||
character_ids = characters |> Enum.map(& &1.id)
|
||||
|
||||
characters
|
||||
|> Enum.each(fn character ->
|
||||
WandererAppWeb.Presence.update(caller_pid, map_id, character.id, %{
|
||||
character_ids
|
||||
|> Enum.each(fn character_id ->
|
||||
WandererAppWeb.Presence.update(caller_pid, map_id, character_id, %{
|
||||
tracked: false,
|
||||
from: DateTime.utc_now()
|
||||
})
|
||||
end)
|
||||
|
||||
WandererApp.Map.Server.untrack_characters(map_id, character_ids)
|
||||
# WandererApp.Map.Server.untrack_characters(map_id, character_ids)
|
||||
|
||||
:ok
|
||||
else
|
||||
@@ -249,19 +246,19 @@ defmodule WandererApp.Character.TrackingUtils do
|
||||
end
|
||||
end
|
||||
|
||||
def add_characters([], _map_id, _track_character), do: :ok
|
||||
# def add_characters([], _map_id, _track_character), do: :ok
|
||||
|
||||
def add_characters([character | characters], map_id, track_character) do
|
||||
:ok = WandererApp.Map.Server.add_character(map_id, character, track_character)
|
||||
add_characters(characters, map_id, track_character)
|
||||
end
|
||||
# def add_characters([character | characters], map_id, track_character) do
|
||||
# :ok = WandererApp.Map.Server.add_character(map_id, character, track_character)
|
||||
# add_characters(characters, map_id, track_character)
|
||||
# end
|
||||
|
||||
def remove_characters([], _map_id), do: :ok
|
||||
# def remove_characters([], _map_id), do: :ok
|
||||
|
||||
def remove_characters([character | characters], map_id) do
|
||||
:ok = WandererApp.Map.Server.remove_character(map_id, character.id)
|
||||
remove_characters(characters, map_id)
|
||||
end
|
||||
# def remove_characters([character | characters], map_id) do
|
||||
# :ok = WandererApp.Map.Server.remove_character(map_id, character.id)
|
||||
# remove_characters(characters, map_id)
|
||||
# end
|
||||
|
||||
def get_main_character(
|
||||
nil,
|
||||
|
||||
@@ -96,7 +96,7 @@ defmodule WandererApp.Map do
|
||||
map_id
|
||||
|> get_map!()
|
||||
|> Map.get(:characters, [])
|
||||
|> Enum.map(&WandererApp.Character.get_character!(&1))
|
||||
|> Enum.map(fn character_id -> WandererApp.Character.get_map_character!(map_id, character_id) end)
|
||||
|
||||
def list_systems(map_id),
|
||||
do: {:ok, map_id |> get_map!() |> Map.get(:systems, Map.new()) |> Map.values()}
|
||||
|
||||
@@ -5,25 +5,22 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
|
||||
alias WandererApp.Map.Server.{Impl, ConnectionsImpl, SystemsImpl}
|
||||
|
||||
def get_characters(%{map_id: map_id} = _state),
|
||||
do: {:ok, map_id |> WandererApp.Map.list_characters()}
|
||||
|
||||
def add_character(%{map_id: map_id} = state, %{id: character_id} = character, track_character) do
|
||||
Task.start_link(fn ->
|
||||
with :ok <- map_id |> WandererApp.Map.add_character(character),
|
||||
{:ok, _} <-
|
||||
{:ok, _settings} <-
|
||||
WandererApp.MapCharacterSettingsRepo.create(%{
|
||||
character_id: character_id,
|
||||
map_id: map_id,
|
||||
tracked: track_character
|
||||
}),
|
||||
{:ok, character} <- WandererApp.Character.get_character(character_id) do
|
||||
{:ok, character} <- WandererApp.Character.get_map_character(map_id, character_id) do
|
||||
Impl.broadcast!(map_id, :character_added, character)
|
||||
:telemetry.execute([:wanderer_app, :map, :character, :added], %{count: 1})
|
||||
:ok
|
||||
else
|
||||
_error ->
|
||||
{:ok, character} = WandererApp.Character.get_character(character_id)
|
||||
{:ok, character} = WandererApp.Character.get_map_character(map_id, character_id)
|
||||
Impl.broadcast!(map_id, :character_added, character)
|
||||
:ok
|
||||
end
|
||||
@@ -35,7 +32,7 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
def remove_character(map_id, character_id) do
|
||||
Task.start_link(fn ->
|
||||
with :ok <- WandererApp.Map.remove_character(map_id, character_id),
|
||||
{:ok, character} <- WandererApp.Character.get_character(character_id) do
|
||||
{:ok, character} <- WandererApp.Character.get_map_character(map_id, character_id) do
|
||||
Impl.broadcast!(map_id, :character_removed, character)
|
||||
|
||||
:telemetry.execute([:wanderer_app, :map, :character, :removed], %{count: 1})
|
||||
@@ -64,7 +61,9 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
map_tracked_character_ids
|
||||
|> Enum.filter(fn character -> character in tracked_characters end)
|
||||
|
||||
{:ok, old_map_tracked_characters} = WandererApp.Cache.lookup("maps:#{map_id}:tracked_characters", [])
|
||||
{:ok, old_map_tracked_characters} =
|
||||
WandererApp.Cache.lookup("maps:#{map_id}:tracked_characters", [])
|
||||
|
||||
characters_to_remove = old_map_tracked_characters -- map_active_tracked_characters
|
||||
|
||||
{:ok, invalidate_character_ids} =
|
||||
@@ -73,7 +72,11 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
[]
|
||||
)
|
||||
|
||||
WandererApp.Cache.insert("map_#{map_id}:invalidate_character_ids", (invalidate_character_ids ++ characters_to_remove) |> Enum.uniq())
|
||||
WandererApp.Cache.insert(
|
||||
"map_#{map_id}:invalidate_character_ids",
|
||||
(invalidate_character_ids ++ characters_to_remove) |> Enum.uniq()
|
||||
)
|
||||
|
||||
WandererApp.Cache.insert("maps:#{map_id}:tracked_characters", map_active_tracked_characters)
|
||||
|
||||
:ok
|
||||
@@ -84,12 +87,26 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
do:
|
||||
character_ids
|
||||
|> Enum.each(fn character_id ->
|
||||
WandererApp.Character.TrackerManager.update_track_settings(character_id, %{
|
||||
map_id: map_id,
|
||||
track: false
|
||||
})
|
||||
if is_character_map_active?(map_id, character_id) do
|
||||
WandererApp.Character.TrackerManager.update_track_settings(character_id, %{
|
||||
map_id: map_id,
|
||||
track: false
|
||||
})
|
||||
|
||||
Impl.broadcast!(map_id, :untrack_character, character_id)
|
||||
end
|
||||
end)
|
||||
|
||||
def is_character_map_active?(map_id, character_id) do
|
||||
case WandererApp.Character.get_character_state(character_id) do
|
||||
{:ok, %{active_maps: active_maps}} ->
|
||||
map_id in active_maps
|
||||
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_characters(map_id, owner_id) do
|
||||
{:ok, invalidate_character_ids} =
|
||||
WandererApp.Cache.lookup(
|
||||
@@ -265,7 +282,7 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
end
|
||||
|
||||
defp update_character(map_id, character_id) do
|
||||
{:ok, character} = WandererApp.Character.get_character(character_id)
|
||||
{:ok, character} = WandererApp.Character.get_map_character(map_id, character_id)
|
||||
Impl.broadcast!(map_id, :character_updated, character)
|
||||
end
|
||||
|
||||
@@ -315,15 +332,18 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
is_nil(structure_id) and is_nil(station_id)
|
||||
end
|
||||
|
||||
defp track_character(map_id, character_id),
|
||||
do:
|
||||
WandererApp.Character.TrackerManager.update_track_settings(character_id, %{
|
||||
map_id: map_id,
|
||||
track: true,
|
||||
track_online: true,
|
||||
track_location: true,
|
||||
track_ship: true
|
||||
})
|
||||
defp track_character(map_id, character_id) do
|
||||
{:ok, character} = WandererApp.Character.get_character(character_id)
|
||||
add_character(%{map_id: map_id}, character, true)
|
||||
|
||||
WandererApp.Character.TrackerManager.update_track_settings(character_id, %{
|
||||
map_id: map_id,
|
||||
track: true,
|
||||
track_online: true,
|
||||
track_location: true,
|
||||
track_ship: true
|
||||
})
|
||||
end
|
||||
|
||||
defp maybe_update_online(map_id, character_id) do
|
||||
with {:ok, old_online} <-
|
||||
@@ -394,8 +414,7 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
{:ok, old_structure_id} =
|
||||
WandererApp.Cache.lookup("map:#{map_id}:character:#{character_id}:structure_id")
|
||||
|
||||
{:ok,
|
||||
%{solar_system_id: solar_system_id, structure_id: structure_id, station_id: station_id}} =
|
||||
{:ok, %{solar_system_id: solar_system_id, structure_id: structure_id, station_id: station_id}} =
|
||||
WandererApp.Character.get_character(character_id)
|
||||
|
||||
WandererApp.Cache.insert(
|
||||
@@ -413,14 +432,15 @@ defmodule WandererApp.Map.Server.CharactersImpl do
|
||||
structure_id
|
||||
)
|
||||
|
||||
if solar_system_id != old_solar_system_id || structure_id != old_structure_id || station_id != old_station_id do
|
||||
if solar_system_id != old_solar_system_id || structure_id != old_structure_id ||
|
||||
station_id != old_station_id do
|
||||
[
|
||||
{:character_location,
|
||||
%{
|
||||
solar_system_id: solar_system_id,
|
||||
structure_id: structure_id,
|
||||
station_id: station_id
|
||||
}, %{solar_system_id: old_solar_system_id}}
|
||||
%{
|
||||
solar_system_id: solar_system_id,
|
||||
structure_id: structure_id,
|
||||
station_id: station_id
|
||||
}, %{solar_system_id: old_solar_system_id}}
|
||||
]
|
||||
else
|
||||
[:skip]
|
||||
|
||||
@@ -93,7 +93,6 @@ defmodule WandererApp.Map.Server.Impl do
|
||||
Process.send_after(self(), :cleanup_connections, 5_000)
|
||||
Process.send_after(self(), :cleanup_systems, 10_000)
|
||||
Process.send_after(self(), :cleanup_characters, :timer.minutes(5))
|
||||
Process.send_after(self(), :cleanup_signatures, :timer.minutes(30))
|
||||
Process.send_after(self(), :backup_state, @backup_state_timeout)
|
||||
|
||||
WandererApp.Cache.insert("map_#{map_id}:started", true)
|
||||
@@ -312,11 +311,6 @@ defmodule WandererApp.Map.Server.Impl do
|
||||
state
|
||||
end
|
||||
|
||||
def handle_event(:cleanup_signatures, state) do
|
||||
Process.send_after(self(), :cleanup_signatures, :timer.minutes(30))
|
||||
state |> SignaturesImpl.cleanup_signatures()
|
||||
end
|
||||
|
||||
def handle_event(msg, state) do
|
||||
Logger.warning("Unhandled event: #{inspect(msg)}")
|
||||
|
||||
|
||||
@@ -25,7 +25,10 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
|
||||
)
|
||||
when not is_nil(char_id) do
|
||||
with {:ok, system} <-
|
||||
MapSystem.read_by_map_and_solar_system(%{map_id: map_id, solar_system_id: system_solar_id}),
|
||||
MapSystem.read_by_map_and_solar_system(%{
|
||||
map_id: map_id,
|
||||
solar_system_id: system_solar_id
|
||||
}),
|
||||
{:ok, %{eve_id: char_eve_id}} <- Character.get_character(char_id) do
|
||||
do_update_signatures(
|
||||
state,
|
||||
@@ -84,9 +87,11 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
|
||||
|
||||
# 3. Additions & restorations
|
||||
added_eve_ids = Enum.map(added_sigs, & &1.eve_id)
|
||||
existing_index = MapSystemSignature.by_system_id_all!(system.id)
|
||||
|> Enum.filter(&(&1.eve_id in added_eve_ids))
|
||||
|> Map.new(&{&1.eve_id, &1})
|
||||
|
||||
existing_index =
|
||||
MapSystemSignature.by_system_id_all!(system.id)
|
||||
|> Enum.filter(&(&1.eve_id in added_eve_ids))
|
||||
|> Map.new(&{&1.eve_id, &1})
|
||||
|
||||
added_sigs
|
||||
|> Enum.each(fn sig ->
|
||||
@@ -97,7 +102,17 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
|
||||
%MapSystemSignature{deleted: true} = deleted_sig ->
|
||||
MapSystemSignature.update!(
|
||||
deleted_sig,
|
||||
Map.take(sig, [:name, :description, :kind, :group, :type, :custom_info, :deleted])
|
||||
Map.take(sig, [
|
||||
:name,
|
||||
:description,
|
||||
:kind,
|
||||
:group,
|
||||
:type,
|
||||
:character_eve_id,
|
||||
:custom_info,
|
||||
:deleted,
|
||||
:update_forced_at
|
||||
])
|
||||
)
|
||||
|
||||
_ ->
|
||||
@@ -107,7 +122,12 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
|
||||
|
||||
# 4. Activity tracking
|
||||
if added_ids != [] do
|
||||
track_activity(:signatures_added, state.map_id, system.solar_system_id, user_id, character_eve_id,
|
||||
track_activity(
|
||||
:signatures_added,
|
||||
state.map_id,
|
||||
system.solar_system_id,
|
||||
user_id,
|
||||
character_eve_id,
|
||||
added_ids
|
||||
)
|
||||
end
|
||||
@@ -152,8 +172,13 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
|
||||
|
||||
defp apply_update_signature(%MapSystemSignature{} = existing, update_params)
|
||||
when not is_nil(update_params) do
|
||||
case MapSystemSignature.update(existing, update_params) do
|
||||
{:ok, _} -> :ok
|
||||
case MapSystemSignature.update(
|
||||
existing,
|
||||
update_params |> Map.put(:update_forced_at, DateTime.utc_now())
|
||||
) do
|
||||
{:ok, _updated} ->
|
||||
:ok
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("Failed to update signature #{existing.id}: #{inspect(reason)}")
|
||||
end
|
||||
|
||||
@@ -1,8 +1,37 @@
|
||||
defmodule WandererApp.MapCharacterSettingsRepo do
|
||||
use WandererApp, :repository
|
||||
|
||||
def create(settings),
|
||||
do: WandererApp.Api.MapCharacterSettings.create(settings)
|
||||
def get(map_id, character_id) do
|
||||
case WandererApp.Api.MapCharacterSettings.read_by_map_and_character(%{
|
||||
map_id: map_id,
|
||||
character_id: character_id
|
||||
}) do
|
||||
{:ok, settings} when not is_nil(settings) ->
|
||||
{:ok, settings}
|
||||
|
||||
_ ->
|
||||
WandererApp.Api.MapCharacterSettings.create(%{
|
||||
character_id: character_id,
|
||||
map_id: map_id,
|
||||
tracked: false
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
def create(settings) do
|
||||
WandererApp.Api.MapCharacterSettings.create(settings)
|
||||
end
|
||||
|
||||
def update(map_id, character_id, updated_settings) do
|
||||
case get(map_id, character_id) do
|
||||
{:ok, settings} when not is_nil(settings) ->
|
||||
settings
|
||||
|> WandererApp.Api.MapCharacterSettings.update(updated_settings)
|
||||
|
||||
_ ->
|
||||
{:ok, nil}
|
||||
end
|
||||
end
|
||||
|
||||
def get_tracked_by_map_filtered(map_id, character_ids),
|
||||
do:
|
||||
|
||||
@@ -91,6 +91,8 @@ defmodule WandererAppWeb.CharactersTrackingLive do
|
||||
character_setting
|
||||
|> WandererApp.MapCharacterSettingsRepo.untrack!()
|
||||
|
||||
WandererApp.Map.Server.untrack_characters(selected_map.id, [character_setting.character_id])
|
||||
|
||||
_ ->
|
||||
character_setting
|
||||
|> WandererApp.MapCharacterSettingsRepo.track!()
|
||||
|
||||
@@ -32,6 +32,16 @@ defmodule WandererAppWeb.MapCharactersEventHandler do
|
||||
)
|
||||
end
|
||||
|
||||
def handle_server_event(%{event: :untrack_character, payload: character_id}, %{
|
||||
assigns: %{
|
||||
map_id: map_id
|
||||
}
|
||||
} = socket) do
|
||||
:ok = WandererApp.Character.TrackingUtils.untrack([%{id: character_id}], map_id, self())
|
||||
socket
|
||||
end
|
||||
|
||||
|
||||
def handle_server_event(
|
||||
%{event: :characters_updated},
|
||||
%{
|
||||
@@ -342,9 +352,6 @@ defmodule WandererAppWeb.MapCharactersEventHandler do
|
||||
self()
|
||||
)
|
||||
|
||||
:ok =
|
||||
WandererApp.Character.TrackingUtils.add_characters(map_characters, map_id, track_character)
|
||||
|
||||
socket
|
||||
end
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ defmodule WandererAppWeb.MapCoreEventHandler do
|
||||
case track_character do
|
||||
false ->
|
||||
:ok = WandererApp.Character.TrackingUtils.untrack(map_characters, map_id, self())
|
||||
:ok = WandererApp.Character.TrackingUtils.remove_characters(map_characters, map_id)
|
||||
|
||||
_ ->
|
||||
:ok =
|
||||
@@ -67,13 +66,6 @@ defmodule WandererAppWeb.MapCoreEventHandler do
|
||||
true,
|
||||
self()
|
||||
)
|
||||
|
||||
:ok =
|
||||
WandererApp.Character.TrackingUtils.add_characters(
|
||||
map_characters,
|
||||
map_id,
|
||||
track_character
|
||||
)
|
||||
end
|
||||
|
||||
socket
|
||||
|
||||
@@ -84,11 +84,7 @@ defmodule WandererAppWeb.MapCharactersLive do
|
||||
character_setting ->
|
||||
case character_setting.tracked do
|
||||
true ->
|
||||
{:ok, map_character_settings} =
|
||||
character_setting
|
||||
|> WandererApp.MapCharacterSettingsRepo.untrack()
|
||||
|
||||
WandererApp.Map.Server.remove_character(map_id, map_character_settings.character_id)
|
||||
WandererApp.Map.Server.untrack_characters(map_id, [character_setting.character_id])
|
||||
|
||||
socket |> put_flash(:info, "Character untracked!") |> load_characters()
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ defmodule WandererAppWeb.MapEventHandler do
|
||||
:characters_updated,
|
||||
:present_characters_updated,
|
||||
:refresh_user_characters,
|
||||
:show_tracking
|
||||
:show_tracking,
|
||||
:untrack_character
|
||||
]
|
||||
|
||||
@map_characters_ui_events [
|
||||
|
||||
2
mix.exs
2
mix.exs
@@ -3,7 +3,7 @@ defmodule WandererApp.MixProject do
|
||||
|
||||
@source_url "https://github.com/wanderer-industries/wanderer"
|
||||
|
||||
@version "1.65.1"
|
||||
@version "1.65.7"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
defmodule WandererApp.Repo.Migrations.AddSigUpdateForcedAt do
|
||||
@moduledoc """
|
||||
Updates resources based on their most recent snapshots.
|
||||
|
||||
This file was autogenerated with `mix ash_postgres.generate_migrations`
|
||||
"""
|
||||
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
alter table(:map_system_signatures_v1) do
|
||||
add :update_forced_at, :utc_datetime
|
||||
end
|
||||
end
|
||||
|
||||
def down do
|
||||
alter table(:map_system_signatures_v1) do
|
||||
remove :update_forced_at
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
defmodule WandererApp.Repo.Migrations.AddMapCharacterTrackingInfo do
|
||||
@moduledoc """
|
||||
Updates resources based on their most recent snapshots.
|
||||
|
||||
This file was autogenerated with `mix ash_postgres.generate_migrations`
|
||||
"""
|
||||
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
alter table(:map_character_settings_v1) do
|
||||
add :encrypted_ship, :binary
|
||||
add :encrypted_ship_name, :binary
|
||||
add :encrypted_ship_item_id, :binary
|
||||
add :encrypted_solar_system_id, :binary
|
||||
add :encrypted_structure_id, :binary
|
||||
add :encrypted_station_id, :binary
|
||||
end
|
||||
end
|
||||
|
||||
def down do
|
||||
alter table(:map_character_settings_v1) do
|
||||
remove :encrypted_station_id
|
||||
remove :encrypted_structure_id
|
||||
remove :encrypted_solar_system_id
|
||||
remove :encrypted_ship_item_id
|
||||
remove :encrypted_ship_name
|
||||
remove :encrypted_ship
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,206 @@
|
||||
{
|
||||
"attributes": [
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"gen_random_uuid()\")",
|
||||
"generated?": false,
|
||||
"primary_key?": true,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "false",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "tracked",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "false",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "followed",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "inserted_at",
|
||||
"type": "utc_datetime_usec"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "updated_at",
|
||||
"type": "utc_datetime_usec"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": true,
|
||||
"references": {
|
||||
"deferrable": false,
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"index?": false,
|
||||
"match_type": null,
|
||||
"match_with": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "map_character_settings_v1_map_id_fkey",
|
||||
"on_delete": null,
|
||||
"on_update": null,
|
||||
"primary_key?": true,
|
||||
"schema": "public",
|
||||
"table": "maps_v1"
|
||||
},
|
||||
"size": null,
|
||||
"source": "map_id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": true,
|
||||
"references": {
|
||||
"deferrable": false,
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"index?": false,
|
||||
"match_type": null,
|
||||
"match_with": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "map_character_settings_v1_character_id_fkey",
|
||||
"on_delete": null,
|
||||
"on_update": null,
|
||||
"primary_key?": true,
|
||||
"schema": "public",
|
||||
"table": "character_v1"
|
||||
},
|
||||
"size": null,
|
||||
"source": "character_id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "encrypted_ship",
|
||||
"type": "binary"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "encrypted_ship_name",
|
||||
"type": "binary"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "encrypted_ship_item_id",
|
||||
"type": "binary"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "encrypted_solar_system_id",
|
||||
"type": "binary"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "encrypted_structure_id",
|
||||
"type": "binary"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "encrypted_station_id",
|
||||
"type": "binary"
|
||||
}
|
||||
],
|
||||
"base_filter": null,
|
||||
"check_constraints": [],
|
||||
"custom_indexes": [],
|
||||
"custom_statements": [],
|
||||
"has_create_action": true,
|
||||
"hash": "3F585D1C545A5264AEFA05502C0F625F9B27B15CA36699DCF37E4F834E6339AE",
|
||||
"identities": [
|
||||
{
|
||||
"all_tenants?": false,
|
||||
"base_filter": null,
|
||||
"index_name": "map_character_settings_v1_uniq_map_character_index",
|
||||
"keys": [
|
||||
{
|
||||
"type": "atom",
|
||||
"value": "map_id"
|
||||
},
|
||||
{
|
||||
"type": "atom",
|
||||
"value": "character_id"
|
||||
}
|
||||
],
|
||||
"name": "uniq_map_character",
|
||||
"nils_distinct?": true,
|
||||
"where": null
|
||||
}
|
||||
],
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"repo": "Elixir.WandererApp.Repo",
|
||||
"schema": null,
|
||||
"table": "map_character_settings_v1"
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"attributes": [
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"gen_random_uuid()\")",
|
||||
"generated?": false,
|
||||
"primary_key?": true,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "eve_id",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "character_eve_id",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "name",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "description",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "type",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "linked_system_id",
|
||||
"type": "bigint"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "kind",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "group",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "custom_info",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "false",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "deleted",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "update_forced_at",
|
||||
"type": "utc_datetime"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "inserted_at",
|
||||
"type": "utc_datetime_usec"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "updated_at",
|
||||
"type": "utc_datetime_usec"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": {
|
||||
"deferrable": false,
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"index?": false,
|
||||
"match_type": null,
|
||||
"match_with": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "map_system_signatures_v1_system_id_fkey",
|
||||
"on_delete": null,
|
||||
"on_update": null,
|
||||
"primary_key?": true,
|
||||
"schema": "public",
|
||||
"table": "map_system_v1"
|
||||
},
|
||||
"size": null,
|
||||
"source": "system_id",
|
||||
"type": "uuid"
|
||||
}
|
||||
],
|
||||
"base_filter": null,
|
||||
"check_constraints": [],
|
||||
"custom_indexes": [],
|
||||
"custom_statements": [],
|
||||
"has_create_action": true,
|
||||
"hash": "915C0896211ECCB6C38871664117E7D470C794825536E7F0887DC5B92681F17B",
|
||||
"identities": [
|
||||
{
|
||||
"all_tenants?": false,
|
||||
"base_filter": null,
|
||||
"index_name": "map_system_signatures_v1_uniq_system_eve_id_index",
|
||||
"keys": [
|
||||
{
|
||||
"type": "atom",
|
||||
"value": "system_id"
|
||||
},
|
||||
{
|
||||
"type": "atom",
|
||||
"value": "eve_id"
|
||||
}
|
||||
],
|
||||
"name": "uniq_system_eve_id",
|
||||
"nils_distinct?": true,
|
||||
"where": null
|
||||
}
|
||||
],
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"repo": "Elixir.WandererApp.Repo",
|
||||
"schema": null,
|
||||
"table": "map_system_signatures_v1"
|
||||
}
|
||||
Reference in New Issue
Block a user