@WebGet("/das-get-{entity}")
  public WebResponse getEntity(
      @WebUser User user, @PathVar("entity") String entityType, @MaybeJson("id") Object idObj) {
    IDao dao = daoRegistry.getDao(entityType);
    Object id = getIdValue(dao.getIdClass(), idObj);

    Object entity = dao.get(user, id).orElse(null);

    return WebResponse.success(entity);
  }
  @WebPost("/das-create-{entity}")
  public WebResponse createEntity(
      @WebUser User user, @PathVar("entity") String entityType, @JsonParam("props") Map props) {
    IDao dao = daoRegistry.getDao(entityType);

    // TODO: probably need to have a createWithReturn
    Object id = dao.create(user, props);
    Object entity = dao.get(user, id).orElse(null);
    return WebResponse.success(entity);
  }
  @WebPost("/das-update-{entity}")
  public WebResponse updateEntity(
      @WebUser User user,
      @PathVar("entity") String entityType,
      @MaybeJson("id") Object idObj,
      @JsonParam("props") Map props) {
    IDao dao = daoRegistry.getDao(entityType);
    Object id = getIdValue(dao.getIdClass(), idObj);

    int r = dao.update(user, props, id);
    return WebResponse.success(r);
  }
  @WebPost("/das-delete-{entity}")
  public WebResponse deleteEntity(
      @WebUser User user, @PathVar("entity") String entityType, @MaybeJson("id") Object idObj) {
    IDao dao = daoRegistry.getDao(entityType);
    Object id = getIdValue(dao.getIdClass(), idObj);

    int numDeleted = dao.delete(user, id);

    if (numDeleted > 0) {
      return WebResponse.success(id);
    } else {
      return WebResponse.fail(new AppException("Cannot delete " + entityType + " with id " + id));
    }
  }
  @WebGet("/das-list-{entity}")
  public WebResponse listEntity(
      @WebUser User user, @PathVar("entity") String entityType, @JsonParam("filter") Map filter) {
    IDao dao = daoRegistry.getDao(entityType);

    Condition conditions = null;
    if (filter != null) {
      // build the Field Operation and Value from the map, assuming it is "J8QL" map compatible
      // (e.g. "projectId;=":123)
      FieldOpValue[] fovs = Query.fovs(filter);
      conditions = Query.and(fovs);
    }
    List<Object> list = dao.list(user, conditions, 0, 1000);

    return WebResponse.success(list);
  }