From d8138fbe694838de2595e49b7b447e5710b86a47 Mon Sep 17 00:00:00 2001 From: Zeeshaun Date: Tue, 27 Jan 2026 20:41:28 -0600 Subject: [PATCH] sync assets and microservice updates --- README.md | 1 - microservices/CharacterApi/DOCUMENTS.md | 54 ++-- microservices/CharacterApi/Models/Coord.cs | 16 +- .../LocationsApi/Services/LocationStore.cs | 264 +++++++++--------- 4 files changed, 167 insertions(+), 168 deletions(-) diff --git a/README.md b/README.md index 43c7c04..ac0a0aa 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,3 @@ - Flashlight: F - Phone: Tab - Pause menu: Esc - diff --git a/microservices/CharacterApi/DOCUMENTS.md b/microservices/CharacterApi/DOCUMENTS.md index 5e531e7..55315cf 100644 --- a/microservices/CharacterApi/DOCUMENTS.md +++ b/microservices/CharacterApi/DOCUMENTS.md @@ -1,27 +1,27 @@ -# CharacterApi document shapes - -This service expects JSON request bodies for character creation and stores -character documents in MongoDB. - -Inbound JSON documents -- CreateCharacterRequest (`POST /api/characters`) - ```json - { - "name": "string" - } - ``` - -Stored documents (MongoDB) -- Character - ```json - { - "id": "string (ObjectId)", - "ownerUserId": "string", - "name": "string", - "coord": { - "x": "number", - "y": "number" - }, - "createdUtc": "string (ISO-8601 datetime)" - } - ``` +# CharacterApi document shapes + +This service expects JSON request bodies for character creation and stores +character documents in MongoDB. + +Inbound JSON documents +- CreateCharacterRequest (`POST /api/characters`) + ```json + { + "name": "string" + } + ``` + +Stored documents (MongoDB) +- Character + ```json + { + "id": "string (ObjectId)", + "ownerUserId": "string", + "name": "string", + "coord": { + "x": "number", + "y": "number" + }, + "createdUtc": "string (ISO-8601 datetime)" + } + ``` diff --git a/microservices/CharacterApi/Models/Coord.cs b/microservices/CharacterApi/Models/Coord.cs index d9d7544..d709ac7 100644 --- a/microservices/CharacterApi/Models/Coord.cs +++ b/microservices/CharacterApi/Models/Coord.cs @@ -1,8 +1,8 @@ -namespace CharacterApi.Models; - -public class Coord -{ - public int X { get; set; } - - public int Y { get; set; } -} +namespace CharacterApi.Models; + +public class Coord +{ + public int X { get; set; } + + public int Y { get; set; } +} diff --git a/microservices/LocationsApi/Services/LocationStore.cs b/microservices/LocationsApi/Services/LocationStore.cs index 9ae3956..27e753f 100644 --- a/microservices/LocationsApi/Services/LocationStore.cs +++ b/microservices/LocationsApi/Services/LocationStore.cs @@ -1,132 +1,132 @@ -using LocationsApi.Models; -using MongoDB.Bson; -using MongoDB.Driver; - -namespace LocationsApi.Services; - -public class LocationStore -{ - private readonly IMongoCollection _col; - - public LocationStore(IConfiguration cfg) - { - var cs = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017"; - var dbName = cfg["MongoDB:DatabaseName"] ?? "GameDb"; - var client = new MongoClient(cs); - var db = client.GetDatabase(dbName); - var collectionName = "Locations"; - EnsureLocationSchema(db, collectionName); - _col = db.GetCollection(collectionName); - - var coordIndex = Builders.IndexKeys - .Ascending(l => l.Coord.X) - .Ascending(l => l.Coord.Y); - var coordIndexOptions = new CreateIndexOptions { Unique = true }; - _col.Indexes.CreateOne(new CreateIndexModel(coordIndex, coordIndexOptions)); - - EnsureOriginLocation(); - } - - private static void EnsureLocationSchema(IMongoDatabase db, string collectionName) - { - var validator = new BsonDocument - { - { - "$jsonSchema", new BsonDocument - { - { "bsonType", "object" }, - { "required", new BsonArray { "name", "coord", "createdUtc" } }, - { - "properties", new BsonDocument - { - { "name", new BsonDocument { { "bsonType", "string" } } }, - { - "coord", new BsonDocument - { - { "bsonType", "object" }, - { "required", new BsonArray { "x", "y" } }, - { - "properties", new BsonDocument - { - { "x", new BsonDocument { { "bsonType", "int" } } }, - { "y", new BsonDocument { { "bsonType", "int" } } } - } - } - } - }, - { "createdUtc", new BsonDocument { { "bsonType", "date" } } } - } - } - } - } - }; - - var collections = db.ListCollectionNames().ToList(); - if (!collections.Contains(collectionName)) - { - var createCommand = new BsonDocument - { - { "create", collectionName }, - { "validator", validator }, - { "validationAction", "error" } - }; - db.RunCommand(createCommand); - return; - } - - var command = new BsonDocument - { - { "collMod", collectionName }, - { "validator", validator }, - { "validationAction", "error" } - }; - db.RunCommand(command); - } - - public Task CreateAsync(Location location) => _col.InsertOneAsync(location); - - public Task> GetAllAsync() => - _col.Find(Builders.Filter.Empty).ToListAsync(); - - public async Task DeleteAsync(string id) - { - var filter = Builders.Filter.Eq(l => l.Id, id); - var result = await _col.DeleteOneAsync(filter); - return result.DeletedCount > 0; - } - - public async Task UpdateNameAsync(string id, string name) - { - var filter = Builders.Filter.Eq(l => l.Id, id); - var update = Builders.Update.Set(l => l.Name, name); - var result = await _col.UpdateOneAsync(filter, update); - return result.ModifiedCount > 0; - } - - private void EnsureOriginLocation() - { - var filter = Builders.Filter.And( - Builders.Filter.Eq(l => l.Coord.X, 0), - Builders.Filter.Eq(l => l.Coord.Y, 0) - ); - var existing = _col.Find(filter).FirstOrDefault(); - if (existing is not null) - return; - - var origin = new Location - { - Name = "Origin", - Coord = new Coord { X = 0, Y = 0 }, - CreatedUtc = DateTime.UtcNow - }; - - try - { - _col.InsertOne(origin); - } - catch (MongoWriteException ex) when (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) - { - // Another instance seeded it first. - } - } -} +using LocationsApi.Models; +using MongoDB.Bson; +using MongoDB.Driver; + +namespace LocationsApi.Services; + +public class LocationStore +{ + private readonly IMongoCollection _col; + + public LocationStore(IConfiguration cfg) + { + var cs = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017"; + var dbName = cfg["MongoDB:DatabaseName"] ?? "GameDb"; + var client = new MongoClient(cs); + var db = client.GetDatabase(dbName); + var collectionName = "Locations"; + EnsureLocationSchema(db, collectionName); + _col = db.GetCollection(collectionName); + + var coordIndex = Builders.IndexKeys + .Ascending(l => l.Coord.X) + .Ascending(l => l.Coord.Y); + var coordIndexOptions = new CreateIndexOptions { Unique = true }; + _col.Indexes.CreateOne(new CreateIndexModel(coordIndex, coordIndexOptions)); + + EnsureOriginLocation(); + } + + private static void EnsureLocationSchema(IMongoDatabase db, string collectionName) + { + var validator = new BsonDocument + { + { + "$jsonSchema", new BsonDocument + { + { "bsonType", "object" }, + { "required", new BsonArray { "name", "coord", "createdUtc" } }, + { + "properties", new BsonDocument + { + { "name", new BsonDocument { { "bsonType", "string" } } }, + { + "coord", new BsonDocument + { + { "bsonType", "object" }, + { "required", new BsonArray { "x", "y" } }, + { + "properties", new BsonDocument + { + { "x", new BsonDocument { { "bsonType", "int" } } }, + { "y", new BsonDocument { { "bsonType", "int" } } } + } + } + } + }, + { "createdUtc", new BsonDocument { { "bsonType", "date" } } } + } + } + } + } + }; + + var collections = db.ListCollectionNames().ToList(); + if (!collections.Contains(collectionName)) + { + var createCommand = new BsonDocument + { + { "create", collectionName }, + { "validator", validator }, + { "validationAction", "error" } + }; + db.RunCommand(createCommand); + return; + } + + var command = new BsonDocument + { + { "collMod", collectionName }, + { "validator", validator }, + { "validationAction", "error" } + }; + db.RunCommand(command); + } + + public Task CreateAsync(Location location) => _col.InsertOneAsync(location); + + public Task> GetAllAsync() => + _col.Find(Builders.Filter.Empty).ToListAsync(); + + public async Task DeleteAsync(string id) + { + var filter = Builders.Filter.Eq(l => l.Id, id); + var result = await _col.DeleteOneAsync(filter); + return result.DeletedCount > 0; + } + + public async Task UpdateNameAsync(string id, string name) + { + var filter = Builders.Filter.Eq(l => l.Id, id); + var update = Builders.Update.Set(l => l.Name, name); + var result = await _col.UpdateOneAsync(filter, update); + return result.ModifiedCount > 0; + } + + private void EnsureOriginLocation() + { + var filter = Builders.Filter.And( + Builders.Filter.Eq(l => l.Coord.X, 0), + Builders.Filter.Eq(l => l.Coord.Y, 0) + ); + var existing = _col.Find(filter).FirstOrDefault(); + if (existing is not null) + return; + + var origin = new Location + { + Name = "Origin", + Coord = new Coord { X = 0, Y = 0 }, + CreatedUtc = DateTime.UtcNow + }; + + try + { + _col.InsertOne(origin); + } + catch (MongoWriteException ex) when (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) + { + // Another instance seeded it first. + } + } +}