Repository navigation
feat: user management feature (C# API + React frontend) — interview code review exercise - #1
Draft
hashcode-adrien with Copilot wants to merge 2 commits into
Draft
hashcode-adrien with Copilot wants to merge 2 commits into
hashcode-adrien with Copilot wants to merge 2 commits into
Conversation
Agent-Logs-Url: https://github.com/hashcode-adrien/tests/sessions/58958061-f8af-481e-a042-b9300e7cf8cb Co-authored-by: hashcode-adrien <137324736+hashcode-adrien@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add user management functionality with known issues
feat: user management feature (C# API + React frontend) — interview code review exercise
Apr 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a complete but intentionally flawed user management feature (list, search, create) to serve as a technical interview code review exercise for a Senior Fullstack C# / React candidate.
Backend —
backend/UserManagement.Api/Program.cs—DbContextas Singleton, wildcard CORS, hardcoded secrets duplicated fromappsettings.jsonappsettings.json— connection string + JWT key in plaintextUsersController.cs—[AllowAnonymous]on entire controller, blocking.Resultcall,DELETErouted asHttpGet, inconsistent routing, domain entity returned directly, noModelState.IsValidcheckUserService.cs— raw string-concatenated SQL (FromSqlRaw),async void CreateUser, N+1 loop loading orders, silentcatch (Exception) {},Console.WriteLinelogging, undisposedSqlConnection, plaintext password storageCreateUserRequest.cs— no[Required]/[EmailAddress]/[StringLength]annotationsUser.cs—PasswordandInternalNotesserialized without[JsonIgnore]Frontend —
frontend/src/usersApi.ts—API_KEYhardcoded client-side, hardcodedlocalhostbase URL, no error handling,anytypes throughoutuseUsers.ts—useEffectmissingsearchTermdependency (stale closure),setIntervalwith noclearIntervalcleanupUserList.tsx— 200+ line monolith mixing API calls / logic / render, N+1 per-userfetchviaOrdersLoader,key={index}, direct state mutation (users.splice+setUsers), nouseMemoonfilter().sort(), no loading/error states,<div onClick>instead of<button>UserCard.tsx—dangerouslySetInnerHTMLonuser.bio(XSS),<img>withoutalt, password field rendered in plaintextUserForm.tsx— uncontrolled form viadocument.getElementById,type="text"on password input, inputs without<label htmlFor>package.json—momentimported for trivial date formatting, wide^version rangesOriginal prompt
Contexte
Ce dépôt sert de support à un entretien technique pour un poste de Développeur Fullstack Senior C# / React.
Le but de cette Pull Request est de proposer une petite fonctionnalité de gestion d'utilisateurs (listing, recherche, création) avec un backend en C# / ASP.NET Core et un frontend en React + TypeScript.
Structure à créer
Créer une nouvelle branche
feature/user-managementet y ajouter l'arborescence suivante :Ouvrir une Pull Request de
feature/user-managementversmainavec un titre clair (ex:feat: user management (API C# + Front React)) et une description listant succinctement les fichiers ajoutés.Défauts à introduire (OBLIGATOIRE — ne pas corriger)
Côté C# / ASP.NET Core
UserService.GetByName, construire la requête avec une concaténation de chaîne :context.Database.ExecuteSqlRaw("SELECT * FROM Users WHERE Name = '" + name + "'")ou équivalent avecFromSqlRaw.User.Passwordstocké et renvoyé en clair (pas de hash, pas de[JsonIgnore]), et renvoyé dans les réponses API.User(avec Password, dates internes, etc.) au lieu d'un DTO.async void: la méthodeCreateUserdu service est déclaréeasync voidau lieu deasync Task..Resultou.Wait()sur une méthode async (ex:var users = _service.GetAllAsync().Result;).CancellationToken.CreateUserRequestn'a aucuneDataAnnotation([Required],[EmailAddress],[StringLength]) et le contrôleur ne vérifie pasModelState.IsValid.DbContextenregistré en Singleton : dansProgram.cs,services.AddSingleton<AppDbContext>(...)au lieu deAddDbContext/ Scoped."SuperSecretKey123") sont en dur dansappsettings.jsonET également dupliquées en constantes dans le code.app.UseCors(p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());sans restriction.GetAllrenvoie toute la tableUserssansSkip/Take.GetAllAsync, boucler sur les utilisateurs et charger lesOrdersdans la boucle (foreach (var u in users) { u.Orders = _context.Orders.Where(o => o.UserId == u.Id).ToList(); }) au lieu d'unInclude.try/catchqui faitcatch (Exception) { }silencieusement dansUserService.Console.WriteLine: utiliserConsole.WriteLineau lieu deILogger<T>.[HttpGet("users")]et[Route("api/[controller]")], avec un endpointDELETEenHttpGet(ex:[HttpGet("delete/{id}")]qui supprime un utilisateur).Email,Password,InternalNotes.using: unSqlConnection(ou équivalent) instancié sansusing, jamais disposé.[AllowAnonymous]sur le contrôleur entier alors qu'il manipule des utilisateurs.Côté React / TypeScript
anypartout : typesanysur les props, states et retours de fetch.useEffectavec dépendances manquantes : fetch des users dansuseEffect(() => { fetchUsers(); }, [])alors quefetchUsersdépend de props/state (ex:searchTerm) — pas dans les deps.key={index}dans le.map()deUserList.users.push(newUser); setUsers(users);au lieu desetUsers([...users, newUser]).fetchsanstry/catch, pas d'étatloading, pas d'étaterroraffiché à l'utilisateur.fetch("http://localhost:5000/api/users")directement dans les composants au lieu d'une variable d'environnement.This pull request was created from Copilot chat.